删除单链表中的倒数第k个结点

       算法思想:定义两个指针,pFast和pSlow,都指向头结点,pFast先后移k-1位,使pFast指向第k个结点,此时pSlow就是相对pFast的倒数第k个结点。然后同时后移,当pFast走到表尾时,pSlow正好指向倒数第k个结点。然后将pSlow指向的结点删除。

       删除单链表中的倒数第k个结点,首先要确定倒数第k个结点的位置。


 
 
//查找指向链表中的倒数第k个结点的指针

Node* Find_k_Node(LinkList pHead, int k)
{
	if (pHead == NULL || k < 0)
	{
		return NULL;
	}
	Node* pFast = pHead;
	Node* pSlow = pHead;
	//pFast指针后移k-1位
	while (--k)
	{
		pFast = pFast->Next;
	}
	//循环结束后pFast指向表尾,pSlow指向链表的倒数第k个结点
	while (pHead&&(pFast->Next))
	{
		pSlow = pSlow->Next;
		pFast = pFast->Next;
	}
	//返回指向倒数第k个结点的指针
	return pSlow;
}


//删除链表中的倒数第k个结点
int Del_k_Node(LinkList pHead, int k)
{
	if (k < 1 || k > length(pHead))
	{
		printf("input error!\n");
		return NULL;
	}
	//调用Find_k_Node,得到指向倒数第k个结点的指针
	Node* pDel = Find_k_Node(pHead, k);
	Node* pPre = pHead;
	Node* pNext = pDel->Next;
	//使pPre从pHead开始后移,循环结束时,pPre->Next=pDl;
	while (pPre->Next != pDel)
	{
		pPre = pPre->Next;
	}
	pPre->Next = pNext;
	free(pDel);
	//打印删除倒数第k个结点后链表中的元素
	PrintList(pHead);
	return 0;
}

完整源代码:

#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>

typedef int DataType;

typedef struct Node
{
	DataType Data;
	struct Node* Next;
}Node, *LinkList;
//初始化,将头指针pHead置空
void InitList(LinkList* pHead)
{
	*pHead = NULL;
}

//尾插,在表尾插入一个元素data

void PushBack(LinkList* pHead, DataType data)
{
	//如果链表为空则头插一个元素data
	if (NULL == (*pHead))
	{
		*pHead = (LinkList)malloc(sizeof(Node));
		if (NULL == *pHead)
		{
			printf("申请空间失败!\n");
		}
		(*pHead)->Data = data;
		(*pHead)->Next = NULL;
		/*PushFornt(pHead, data);*/
		return;
	}

	Node* pCur = (*pHead);

	Node* pNewNode = (LinkList)malloc(sizeof(Node));
	if (pNewNode == NULL)
	{
		printf("申请空间失败!\n");
	}
	//跳出循环时pCur指向链表的尾结点
	while (pCur->Next != NULL)
	{
		pCur = pCur->Next;
	}
	pNewNode->Data = data;
	pCur->Next = pNewNode;
	pNewNode->Next = NULL;
}
//求表长,求链表中元素的个数

int length(LinkList pHead)
{
	if (pHead == NULL)
	{
		return 0;
	}
	int count = 0;
	Node* p;
	p = pHead;
	while (p)
	{
		p = p->Next;
		count++;
	}
	return count;
}

//打印表中元素

void PrintList(LinkList pHead)
{
	Node* pCur = pHead;
	while (pCur)
	{
		printf("%-3d", pCur->Data);
		pCur = pCur->Next;
	}
	printf("\n");
}
//查找指向链表中的倒数第k个结点的指针

Node* Find_k_Node(LinkList pHead, int k)
{
	if (pHead == NULL || k < 0)
	{
		return NULL;
	}
	Node* pFast = pHead;
	Node* pSlow = pHead;
	//pFast指针后移k-1位
	while (--k)
	{
		pFast = pFast->Next;
	}
	//循环结束后pFast指向表尾,pSlow指向链表的倒数第k个结点
	while (pHead && (pFast->Next))
	{
		pSlow = pSlow->Next;
		pFast = pFast->Next;
	}
	//返回指向倒数第k个结点的指针
	return pSlow;
}

//删除链表中的倒数第k个结点
int Del_k_Node(LinkList pHead, int k)
{
	if (k < 1 || k > length(pHead))
	{
		printf("input error!\n");
		return NULL;
	}
	//调用Find_k_Node,得到指向倒数第k个结点的指针
	Node* pDel = Find_k_Node(pHead, k);
	Node* pPre = pHead;
	Node* pNext = pDel->Next;
	//使pPre从pHead开始后移,循环结束时,pPre->Next=pDl;
	while (pPre->Next != pDel)
	{
		pPre = pPre->Next;
	}
	pPre->Next = pNext;
	free(pDel);
	//打印删除倒数第k个结点后链表中的元素
	PrintList(pHead);
	return 0;
}

int main()
{
	LinkList L;
	//初使化链表
	InitList(&L);
	int k = 0;
	int data = 0;
	scanf("%d", &data);
	//在链表中循环插入元素data,以-1作为结束标志
	while (data != -1)
	{
		PushBack(&L, data);
		scanf("%d", &data);
	}
	//打印表中元素
	PrintList(L);
	//输入要删除的元素序号k,倒数
	scanf("%d", &k);
	//删除表L中的倒数第k个结点,并打印删除后链表中的元素
	Del_k_Node(L, k);
	system("pause");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/liubo_01/article/details/80341377