題目描述:
輸入一個單向鏈表,輸出該鏈表中倒數第k個結點。
分析:
方法1:要輸出鏈表中的倒數第K個結點,最自然的想法是先求出鏈表的長度N,然後從頭遍曆鏈表輸出鏈表的第N-K+1個結點即可。注意本題數字從1計數,也就是說倒數第1個節點是鏈表最後一個結點。例如鏈表長度為4,需要輸出倒數第2個結點,則我們只需要從頭開始輸出鏈表第3個結點即可。該思路代碼如下:
struct node { int data; struct node* next;};struct node *getK1(struct node *list, int k){ int n = length(list); //求出鏈表長度 if (k > n) return NULL; struct node *current = list; int i = 0; for (; i<n-k; i++) //遍曆鏈表,找出第N-K+1個結點 current = current->next; return current;}int length(struct node *head){ struct node *current = head; int count = 0; while (current != NULL) { count++; current = current->next; } return count;}
方法2:方法1需要遍曆鏈表2遍,第1遍求長度,第2遍求結點。另外一種比較巧妙的方法是不求鏈表長度,只需遍曆鏈表一遍即可。方法如下:設定兩個指標p1,p2,首先p1和p2都指向head,然後p2向前走k步,這樣p1和p2之間就間隔k個節點。最後p1和p2同時向前移動,p2走到鏈表末尾的時候p1剛好指向倒數第K個結點。該方法代碼如下:
struct node *getK(struct node *head, int k){ struct node *p1, *p2; p1 = p2 = head; //都指向鏈表頭 for (; k>0 && p2!=NULL; k--) p2 = p2->next; //p2先走k步 if (k > 0) return NULL; //如果鏈表長度不夠,返回NULL while (p2 != NULL) { //現在p1和p2同時移動 p1 = p1->next; p2 = p2->next; } return p1;}