/*****************************************************
题目:输入一个链表,输出该链表倒数第K个节点。例如有一个
链表有6个节点,从头到尾他们的值依次是1,2,3,4,5,6.这个链
表倒数第3个节点是值为4的节点。
*****************************************************/
#include<stdio.h>
//链表节点结构
struct ListNode{
int m_nValue;
ListNode* m_pNext;
};
//创建链表节点
ListNode* createListNode(int value)
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
//连接链表结点
void connectListNode(ListNode* pNode1, ListNode* pNode2)
{
if(!pNode1 || !pNode2)
return;
pNode1->m_pNext = pNode2;
}
//查找倒数第N个节点
ListNode* find_KthNode(ListNode* pHead, unsigned int k)
{
if(!pHead || k<0) //注意判断参数有效性,使代码鲁棒性健壮
return 0;
ListNode* pNode1 = pHead;
ListNode* pNode2 = pHead;
//找到离开始点后的第n-1个点
for(int i = 0; i<k-1; ++i)
{
if(pNode2->m_pNext)
pNode2 = pNode2->m_pNext;
else //排除链表节点数小于k的情况,使代码鲁棒性健壮
return NULL;
}
//两个链表指针都往后移动,直到第二个指针指向尾节点,
//则第一个指针就是倒数第k个节点
while(pNode2->m_pNext != NULL)
{
pNode1 = pNode1->m_pNext;
pNode2 = pNode2->m_pNext;
}
return pNode1;
}
void test()
{
ListNode* pNode1 = createListNode(1);
ListNode* pNode2 = createListNode(2);
ListNode* pNode3 = createListNode(3);
ListNode* pNode4 = createListNode(4);
ListNode* pNode5 = createListNode(5);
ListNode* pNode6 = createListNode(6);
connectListNode(pNode1,pNode2);
connectListNode(pNode2,pNode3);
connectListNode(pNode3,pNode4);
connectListNode(pNode4,pNode5);
connectListNode(pNode5,pNode6);
ListNode* pNode = find_KthNode(pNode1,3);
printf("%d\n",pNode->m_nValue);
}
int main()
{
test();
return 0;
}
==总结:
当我们用一个指针遍历链表不能解决问题的时候,可以尝试两个指针来遍历链表。
可以让其中一个指针遍历的速度快一些,或者让他先走几步。
相关题目:
1.求链表中间节点。
解决办法:使两个指针指向头结点,一个指针走一步,另一个走两个,
当速度快点都走到末尾,慢的就指向中间节点。
2.判断一个单项链表是否形成环形结构
定义两个指针指向头结点,一个走一步,另一个走两步。如果走得快的
跟上走的慢的,说明是环形链表;如果走的快的指针走到了末尾(m_pNext指向NULL)
都没有追上第一个指针,那么不是环形链表。
ListNode* find_KthNode(ListNode* pHead, int k)
{
if(pHead == NULL || k<=0)
throw ("invalid input!");
ListNode* pFrontNode = pHead;
ListNode* pBehNode = pHead;
while(k-- > 1)
{
if(pFrontNode->m_pNext == NULL)
throw ("invalid input");
pFrontNode = pFrontNode->m_pNext;
}
while(pFrontNode->m_pNext)
{
pFrontNode = pFrontNode->m_pNext;
pBehNode = pBehNode->m_pNext;
}
return pBehNode;
}
==参考剑指offer