一、寻找单链表的中间节点
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);
}
}