链表中倒数第K个结点

来源:互联网 发布:网络作家富豪榜2011 编辑:程序博客网 时间:2024/05/21 07:51

题目:输入一个链表,输出该链表中倒数第K个结点。为了符合大多数人的习惯,本醍从一开始计时,即链表的尾结点是倒数第一个结点。例如一个链表有6个结点,从结点开始他们的值依次是1,2,3,4,5,6.这个链表的倒数第3个结点是值为4的结点。

链表结点定义:

strcut ListNode{     int                   m_nValue;     ListNode*       m_pNext;};

为了得到倒数第K个结点
(1)遍历两次链表的方法
很自然的想法是先走到链表的尾端,再从尾端回溯K步。可是我们如果从链表结点的定义链表时是单链表,因此行不通。
既然前面行不通,我们还是把思路回到头结点上来。假设整个链表有n个结点,那么倒数第K个结点就是从头结点开始第n-k+1个结点。如果我们能够得到链表中结点的个数n,那我们只有从头结点开始往后n-k+1步就可以了。也就是说我们需要变遍历链表两次,第一次统计链表的结点个数n,第二次就能找到倒数第k个结点。
(2)遍历一次的方法
为了实现只遍历链表一次就能找到倒数第K个结点,我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持k-1,当第一个指针到达链表的尾结点时,第二个指针正好是倒数第K个结点。


注:(a)第一个指针在链表上走两步。(b)把第二个指针指向链表的头结点。(c)两个指针一同沿着链表向前走。当第一个指针指向链表的尾结点是,第二个指针指向倒数第3个结点。
分析:首先第一个指针从头结点开始想前走两步到达第3个结点。接着我们把第二个指针初始化指向链表的第一个结点。最后让两个指针同时向前遍历,当第一个指针到达链表的尾结点时,第二个指针指向的刚好计时倒数第3个结点。
根据以上的叙述,得到以下的代码:

ListNode* FindKthToTail(ListNode* pListHead,unsigned int k){if(pListHead==NULL||k==0)return NULL;ListNode* pAhead=pListHead;ListNode* pBehind=NULL;for(unsign int i=0;i<k-1;++i){if(pAhed->m_pNext!=NULL)pAhead=pAhead=>m_pNext;else{return NULL;}}pBehind=pListHead;while(pAhead->m_pNext!=NULL){pAhead=pAhead->m_pNext;pBehind=pBehind->m_pNext;}return pBehind;}


                                             
0 0
原创粉丝点击