您的位置:首页 > 其它

算法题:求链表倒数第K个结点

2014-08-04 13:34 225 查看
说明:本文仅供学习交流,转载请标明出处,欢迎转载!

题目:给出一个单链表,返回倒数第K个结点,最后一个结点为倒数第1个

《剑指offer》上面给的解法是设置两个指针,这里记为p1、p2,先让p2走(k-1)步,然后p1、p2同时走,当p2走到最后一个结点时,p1所指向的结点就是倒数第k个结点。

我觉得按照这样的逻辑写代码反而更容易出错,因为我们需要把我两件重要的问题:(1).p2先走(k-1)步;(2)循环结束的条件是p2到达最后一个结点,即p2->next==NULL。显然这样不太容易控制,我的想法是:先让p2先走k步,然后p1,p2一块走,循环结束的条件是p2到达NULL,即p2==NULL,这样比较直观。

我们用Node *FindLastK(Node *head,int k)表示求解函数,同时在要注意以下特殊情况:

(1)处理空链表的情况,即head=NULL的情况;

(2)处理k<1的情况;(注意k从1开始)

(3)处理链表长度小于k的情况。

代码如下:

#include<iostream>
using namespace std;
struct Node
{
int value;
Node* next;
Node(int v):value(v){}
};
/*创建一个链表,1->2->3->4->5->6->7*/
Node* CreateList()//创建一个单链表
{
Node *head;
Node *n1=new Node(1);
Node *n2=new Node(2);
Node *n3=new Node(3);
Node *n4=new Node(4);
Node *n5=new Node(5);
Node *n6=new Node(6);
Node *n7=new Node(7);
head=n1;
n1->next=n2;
n2->next=n3;
n3->next=n4;
n4->next=n5;
n5->next=n6;
n6->next=n7;
n7->next=NULL;
return head;
}
void FreeList(Node *head)//将链表空间释放
{
if(head==NULL)
{
return ;
}
else
{
Node *temp=head->next;
delete head;
head=temp;
FreeList(head);
}
}
void VisitList(Node *head)//遍历链表中的元素,用递归的方法遍历
{
if(head)
{
cout<<head->value<<"->";
VisitList(head->next);
}
else
{
cout<<"null"<<endl;
}
}
Node *FindLastK(Node *head,int k)//查找倒数第K个元素,最后一个元素时倒数第一个
{
if(head==NULL || k<1)
{
return NULL;
}
else
{
Node *pre,*p;
pre=p=head;
int i;
for(i=0;p && i<k;i++)//要保证p存在,p先走k步
{
p=p->next;
}
if(i<k)//说明没走到k步,即k大于链表的长度
{
return NULL;
}
else//如果一切正常,则两者同时走
{
while(p)
{
p=p->next;
pre=pre->next;
}
}
return pre;
}
}
int main()
{
Node *head=CreateList();
cout<<"链表输出为:";
VisitList(head);
int k;
while(cin>>k)
{
Node *temp=FindLastK(head,k);
if(temp)
{
cout<<"倒数第"<<k<<"个元素为:"<<temp->value<<endl;
}
else
{
cout<<"输入的K超过了链表的长度!"<<endl;
}
}
FreeList(head);//释放链表空间
return 0;
}


测试结果如下:






参考资料------《剑指offer》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: