一系列链表题

1、链表的倒序输出:(输出4,3,2,1)在这里,可以使用递归的方式:

<span style="font-size:18px;">void Reverse(pNode pHead)
{
	if(pHead)
	{
		Reverse(pHead->next);
		cout<<pHead->data<<"->";	
	}
}
</span>
2、删除无头单链表的非尾节点(不能遍历)

思路:目前只给出了删除的位置,既然不能遍历,我们就无法知道删除元素节点的前一个位置。这时候我们可以从它的后一个节点入手,可以删除后一个节点,然后将后一个元素的值保留,赋给前一个节点的值。

如图:



实现代码:

<span style="font-size:18px;">void DeleteListNotTail(pNode *pHead,pNode pos)
{
	assert(pHead);
	if(*pHead == NULL || pos->next == NULL)
		return;
	pNode pDel = pos->next;
	pos->next = pDel->next;
	pos->data = pDel->data;
	free(pDel);
}</span>
3、在无头单链表的非头节点处插入一个节点(不能遍历)

思路:可以在位置之后插入一个节点,然后交换两个节点的值。



实现代码:

<span style="font-size:18px;">void InsertNotHead(pNode *pHead,pNode pos,DataType data)
{
	if(*pHead == NULL || pos == *pHead)
		return;
	pNode newNode = BuyNode(pos->data);
	newNode->next = pos->next;
	pos->next = newNode;
	pos->data = data;
}</span>

4、查找单链表的中间节点

思路:可以定义快慢两个指针,一个走一步,一个走两步。当快指针到达终点时,慢指针就在中间位置。

在这里,还得分为奇数个节点和偶数个节点。(偶数个节点有两个中间节点哦)


关于偶数个节点,我们该返回哪一个呢,如果返回3,就让pFast指向NULL,如果返回2,就让pFast->next指向NULL;

如果两个都返回的话,就要用一个结构体来接收哦。



实现代码:

<span style="font-size:18px;">pNode FindMidNode(pNode pHead)
{
	assert(pHead);
	pNode pFast = pHead;
	pNode pSlow = pHead;
	//while(pFast && pFast->next)            //偶数个节点时,中间节点返回后一个
	//{
	//	pFast = pFast->next->next;
	//	pSlow = pSlow->next;
	//}
	while(pFast->next && pFast->next->next)  //偶数个节点时,中间节点返回前一个
	{
		pFast = pFast->next->next;
		pSlow = pSlow->next;
	}
	return pSlow;
}</span>

5、查找倒数第K个节点(只能遍历一次)

思路:用快慢两个指针,先让快指针先走K步,然后快慢指针一起向前走。当快指针指向NULL的时候,慢指针就指向倒数第K个节点。

这里强调的是走K步和走K-1步。(一个是后置--,一个是前置--,二者是不一样的)

<span style="font-size:18px;">pNode FindLastK(pNode pHead,int k)
{
	assert(pHead);
	int count = k;
	pNode pFast = pHead;
	pNode pSlow = pHead;
	if(pHead == NULL || k <= 0)     //边界条件判断
		return NULL;
	/*while(count--)            //pFast移动k次
	{
		if(pFast == NULL)
			return NULL;
		pFast = pFast->next;	
	}

	while(pFast)
	{
		pFast = pFast->next;
		pSlow = pSlow->next;
	}*/

	while(--count)                 //pFast移动k-1次
	{
		if(pFast == NULL)
			return NULL;
		pFast = pFast->next;	
	}

	while(pFast->next)
	{
		pFast = pFast->next;
		pSlow = pSlow->next;
	}
	return pSlow;
}
</span>

6、单链表的逆置/反转

思路:用三个指针互相转换,用2->1,然后再整体向后移动。直到所有的都链起来。


实现代码:

pNode ReverseList(pNode pHead)      //逆置
{
	assert(pHead);
	if(pHead == NULL || pHead->next == NULL)
		return pHead;
	pNode pPre = pHead;
	pNode pCur = pPre->next;
	pNode pNext = pCur->next;

	while(pNext)
	{
		pCur->next = pPre;
		pPre = pCur;
		pCur = pNext;
		pNext = pNext->next;
	}
	pCur->next = pPre;
	pHead->next = NULL;
	return pCur;
}


之后遇到其他链表题的话还会继续补充哦。 微笑 微笑






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值