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 相關題目
- 求鏈表的中間節點,如果鏈表中節點的總數爲奇數,返回中間的節點,如果結點總數爲偶數,返回中間兩個節點的任意一個。爲了解決這個問題,也可以定義兩個指針,同時從鏈表的頭結點出發,一個指針一次走一步,另一個指針一次走兩步。當走的快的指針到達了鏈表的末尾時,走的慢的指針正好在連鏈表的中間。