單鏈表的各種花樣

2022-09-19 14:42:11 字數 1899 閱讀 3239

以下的資料結構基於單鏈表

考慮幾個問題

實現思路

舉個例子,假設鍊錶是1 -> 2 -> 3 -> 4 -> 5 ->6 ->7,m=3,n=5

首先,將頭指標指向2(m-1)的位置,用乙個指標p儲存,再用乙個指標q儲存3(m)位置

然後,開始迭代處理3到5中間(也就是3 -> 4變成4 -> 3,4 -> 5變成5 ->4)

最後,把m-1的next指向n(接頭),把n+1的next指向m(續尾)

void reversebetween(int m, int n) 

p->next = pre;

q->next = cur;

}

說明

當m > 1時,用p代替head移動到m-1,可以保持head原有位置,當m = 1時p就是head副本,p->next = pre使得head也被修改

當n等於鍊錶長度時,cur從for迴圈出來時就是nullptr(就很優雅hahah)

刪除的時候臨時變數儲存中間節點

只有不重複的時候才node才向前移動

void removeduplicate() 

else

node = node->next;

} }

思考幾個問題

原鍊錶是否需要保持不變?如果需要那麼需要使用棧依次彈出兩煉表中較大者插入到新鍊錶中。

若不需要,則可以將要合併的鍊錶插入到合適的位置

void mergelist(node* n2) 

node* temp = q; //q加入到合適位置中

q = q->next; //合併鍊錶向前

temp->next = p->next;

p->next = temp;

++head->elem; //記錄鍊錶元素個數

雙指標法

求中間元素可以讓兩個指標步長差一倍,當快指標到達表尾,慢指標所指就是中間元素

(倒數第k個元素可以保持步長一致,但快指標先走k-1步)

node* findmidelement() 

return p;

}}

雙指標法

怎麼理解有環的時候快慢指標一定會在慢指標一遍迴圈結束前相遇呢?就跟跑操場一樣,跑得快的能在跑得慢的跑完一圈之前再次追上。(快的速度》=慢的速度*2)

int circlelength() 

if (fast == nullptr) //若不成立,則此時slow與fast處在交點位置

return 0;

int count = 1; //這時候定住fast,slow跑一邊環就得到長度了

slow = slow->next;

while (slow != fast)

return count;

}

鍊錶不是二叉樹,有公共節點意味著倆鍊錶會匯聚,但絕不會分流。所以鍊錶的樣子是y型,第乙個公共節點及其之後全是公共節點。

這樣一來就好說了,前邊我們在頭節點儲存了鍊錶的長度,要理解在長鍊錶長度是len1,短鍊表長度是len2時,在長鍊錶的前len1-len2區間是不可能有公共節點的,理由在划下劃線部分。

實現思路:

獲取長度len1,len2

長鍊表向後移動len1-len2個位置

對齊之後開始檢查對應位置是否指標相等,否則同步後移

處理邊界條件,檢查輸入合法性

單鏈表的各種操作

單鏈表的各種操作 define null 0 typedef char elemtype 字元型資料 typedef struct lnode setnull struct lnode p int length struct lnode p elemtype get struct lnode p,i...

單鏈表的各種操作

單鏈表的各種操作 define null 0 typedef char elemtype 字元型資料 typedef struct lnode elemtype data struct lnode next setnull struct lnode p int length struct lnode...

單鏈表的各種操作

單鏈表的各種操作 define null 0 typedef char elemtype 字元型資料 typedef struct lnode setnull struct lnode p int length struct lnode p elemtype get struct lnode p,i...