1 题目描述
输入一个链表,输出链表中倒数第 k 个结点。链表的尾结点是倒数第一个结点。例如一个链表有 6 个结点,从头到尾开始他们的值依次是 1、2、3、4、5、6。那么倒数第三个节点的值是 4 。
2 解法描述
- 常规方法:遍历整个链表计算链表的长度,倒数第 n 个结点,也就是整数第 n-i+1。需要遍历链表两次
- 其他解法:设立两个指针,初始化时同时指向链表中的第一个元素,接下来 head 指针单独向前移动 n 个位置,然后 result 和 head 指针同时往后移动,直到 head 指针为 NULL,此时 result 指针指向倒数第 n 个元素。
3 C 语言实现
#include<stdio.h>
typedef int ElemType;
typedef struct node{
ElemType data;
struct node* next;
}LNode,*LinkList;
void createList_tail(LinkList *L){
ElemType temp;
LNode* p,*r;
*L =(LinkList) malloc (sizeof(LNode));
(*L)->next=NULL;
(*L)->data=-1;
r=(*L);
scanf("%d",&temp);
while(temp != -1){
p=(LinkList) malloc (sizeof(LNode));
p->data = temp;
p->next=NULL;
r->next =p;
r=p;
scanf("%d",&temp);
}
}
LNode* findKthFromTail(LinkList L,int n){
//链表为空或者n没有意义返回NULL
if(L==NULL||n<=0){
return NULL;
}
//
int i;
LNode* head=L->next;
LNode* result=L->next;
for(i=0;i<n;i++){
//要注意链表的长度可能小于 n
if(head!=NULL){
head=head->next;
}else{
return NULL;
}
}
while(head!=NULL){
head=head->next;
result=result->next;
}
return result;
}
void main(){
LinkList L;
createList_tail(&L);
LNode* get=findKthFromTail(0,10);
if(get!=NULL){
printf("%d",get->data);
}
}
注意程序的鲁棒性
1 有可能 n 大于了链表的长度
2 输入的链表没有初始化
4 相关题目
- 求链表的中间节点,如果链表中节点的总数为奇数,返回中间的节点,如果结点总数为偶数,返回中间两个节点的任意一个。为了解决这个问题,也可以定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步。当走的快的指针到达了链表的末尾时,走的慢的指针正好在连链表的中间。