一:單鏈表——③查詢倒數第k個節點(O(1))
阿新 • • 發佈:2019-01-05
製作人 :TheShyclear
製作時間:2018-7-21
製作內容:查詢單鏈表中的倒數第k個數據
版本號 :8.0
缺陷:頭節點只能插入一次,不能在1號節點出插入,詳細看Insert函式
注意:頭指標的不可改變性
思路:單鏈表中的許多問題需要用到兩個指標的配合,因為單鏈表只有後繼節點,無法找到後繼節點。
當我們拿到這個問題時,第一反應肯定是:用一個指標指向頭節點然後呢迴圈計數到最後節點,這樣我們就知道了連結串列的總長度le,然後那麼倒數第k個節點就是第le+1-k個節點,這樣的話時間複雜度就是O(n)。
那麼我們是否有一種更簡便的迅捷的方法呢?使其複雜度為O(1)
具體程式碼實現:
#include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<string.h> typedef int Elemtype; typedef struct ListNode { Elemtype data;//值域 ListNode *m_pNext;//指標域 }ListNode,*PListNode; ListNode* BuyNode() { ListNode* p = (ListNode*)malloc(sizeof(ListNode)); if(NULL == p) { printf("buynode is error:\n"); exit(1); } memset(p,0,sizeof(ListNode)); return p; } void InitList(PListNode &p) { p = BuyNode(); p->m_pNext = NULL; p->data = 0; } int GetLength(PListNode &head)//問題出現:不能直接操作head節點 { int count = 0; PListNode s = head; while(s!=NULL) { count+=1; s=s->m_pNext; } return count; } void InsertList(PListNode &p,Elemtype x,int pos) { if(pos<1 || pos>GetLength(p)+1) { printf("input pos is error:\n"); exit(1); } PListNode s = p;//頭節點 s if(pos == 1) { p->data = x; p->m_pNext = NULL; } else { while(pos-2) { s = s->m_pNext; --pos; }//s指向前驅 PListNode r =s->m_pNext; PListNode q = BuyNode(); q->data = x; s->m_pNext = q; q->m_pNext = r; } } PListNode Find_Kth_To_Tail(PListNode &p,int k) { if(k<1 || k>GetLength(p)) { printf("input k is error:\n"); exit(1); } PListNode s =p; PListNode q =p; for(int i=0;i<k-1;++i) { s = s->m_pNext; } while(s->m_pNext != NULL) { s = s->m_pNext; q = q->m_pNext; } return q; } void Show_List(PListNode &head) { PListNode s =head; while(s != NULL) { printf("%d ",s->data); s = s->m_pNext; } } void main() { PListNode head; InitList(head); for(int i=1;i<5;++i) { InsertList(head,i+10,i); } Show_List(head); PListNode r = Find_Kth_To_Tail(head,2); printf(" "); printf("%d \n",r->data); }
執行結果:
11 12 13 14 13
請按任意鍵繼續. . .