首页 > 代码库 > 算法题:求链表倒数第K个结点
算法题:求链表倒数第K个结点
说明:本文仅供学习交流,转载请标明出处,欢迎转载!
题目:给出一个单链表,返回倒数第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》
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。