寻找和删除链表的中间节点

一、寻找单链表的中间节点

1、情况一:若为奇数直接是中间节点,若为偶数则为中间两个节点的第二个节点

(1)代码如下

SListNode*  FindMidNode1(SListNode* pHead)//偶数的情况在第二个数,并且次程序所有奇情况都满足
{
	if (pHead == NULL)
	{
		return NULL;
	}
	SListNode* slow = pHead;
	SListNode* fast = pHead;
	while (fast != NULL&&fast->_next != NULL)
	{
		fast = fast->_next->_next;
		slow = slow->_next;
	}
	return slow;
}
(2)详细讲解(fast只要后面还有一个节点都会往后面走):
若为奇数:

节点数为1,则直接返回slow

假设奇数个数为1+2K个(K为1、2、3...的整数),因为fast和slow都先走一步(在第一个节点处),所以fasth每次会走到1+2N的节点处(N为0、1、2. ..的整数),最后会走到1+2k的位置上(因为由于1+2N==1+2k,解出N==K),也就是最后一个节点的位置;同理slow每次会走到1+N的位置上,最后会走到1+K的位置上,而对于奇数来说(2K+1)/2=K,,那么K+1便是中间的点

若为偶数:

节点数为2时,fast会先走一步(因为fast只要后面有一个节点就会向前走两步,同时slow也会往后走一步,这时返回slow即可

假设偶数个数为2K个(K为1、2、3...的整数),因为fast和slow都走一步(在第一个节点处),所以fasth每次会走到1+2N的节点处(N为0、1、2. ..的整数),最后会走到1+2K的位置上(因为fast只要后面有一个节点的时候都会往后走,由于1+2N==1+2K,解出N==K),也就是最后NULL节点的位置;同理slow每次会走到1+N的位置上,最后会走到1+K的位置上,而对于偶数来说2K/2=K,,那么K+1便是两个中间节点的后一个节点

2、情况一:若为奇数直接是中间节点,若为偶数则为中间两个节点的第一个节点

(1)代码如下

SListNode* FindMidNode2(SListNode* pHead)//偶数的情况在第一个数,并且次程序所有奇情况都满足
{
	if (pHead == NULL)
	{
		return NULL;
	}
	SListNode* slow = pHead;
	SListNode* fast = pHead;
	while (fast != NULL&&fast->_next != NULL&&fast->_next->_next != NULL)
	{
		slow = slow->_next;
		fast = fast->_next->_next;
	}
	return slow;
}

(2)详细讲解(fast只要后面有两个节点就会往后面走)

若为奇数:

节点素为1,与上面的讲解完全相同

奇数个数为1+2K个(K为1、2、3...的整数),fast还是走到最后一个节点的位置,所以和上面的讲解完全相同

若为偶数:

若节点数为2时,fast不会走,所以直接返回slow即可

假设偶数个数为2K个(K为1、2、3...的整数),因为fast和slow都先走一步(在第一个节点处),所以fasth每次会走到1+2N的节点处(N为0、1、2. ..的整数),最后会走到2K-1的位置上(因为fast只有在后面有两个节点以上的时候才会继续向后走,由于1+2N==2K-1,解出N==K-1),也就是倒数第二个节点的位置;同理slow每次会走到1+N的位置上,最后会走到K的位置上,而对于偶数来说2K/2=K,,那么K便是两个中间节点的一个节点

二、寻找单链表的中间节点

边界条件的判断根据fast什么时候会停止和进行前进来判定,第一种情况只要后面有一个结点就往后走,第二种情况要求后面有两种情况的时候才往后走

1、情况一:若为奇数直接是中间节点,若为偶数则为中间两个节点的第二个节点

代码如下

void RemoveMidNode1(SListNode*& pHead)
{
	if (pHead == NULL)
	{
		return;
	}
	if (pHead->_next == NULL)
	{
		free(pHead);
		pHead = NULL;
	}
	else
	{
		SListNode* slow = pHead;
		SListNode* fast = pHead;
		SListNode* prev = NULL;
		while (fast != NULL&&fast->_next != NULL)
		{
			prev = slow;
			fast = fast->_next->_next;
			slow = slow->_next;
		}
		prev->_next = slow->_next;
		free(slow);
	}
}

2、情况一:若为奇数直接是中间节点,若为偶数则为中间两个节点的第一个节点


代码如下:

void RemoveMidNode2(SListNode*& pHead)
{
	if (pHead == NULL)
	{
		return;
	}
	if (pHead->_next==NULL)
	{
		free(pHead);
		pHead = NULL;
	}
	else if (pHead->_next->_next == NULL)
	{
		SListNode* del = pHead;
		pHead = pHead->_next;
		free(del);
	}
	else
	{
		SListNode* slow = pHead;
		SListNode* fast = pHead;
		SListNode* prev = NULL;
		while (fast!=NULL&&fast->_next!=NULL&&fast->_next->_next!=NULL)
		{
			prev = slow;
			fast = fast->_next->_next;
			slow = slow->_next;
		}
		prev->_next = slow->_next;
		free(slow);
	}
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值