最近一直在看《劍指offer》這本書,現在總結一下對於鍊錶方面的一點認識。
鍊錶的結構很簡單,它由指標把若干個結點連成鏈狀結構。鍊錶的基本操作包括:建立、插入結點、刪除結點等。鍊錶是一種動態儲存結構,在建立鍊錶的時候無需知道鍊錶的長度,當插入乙個結點時,我們只需要為新插入的節點分配記憶體,然後調整指標的指向來確保新插入的結點被鏈結到鍊錶當中。記憶體分配不是在建立鍊錶時一次完成的,而是每新增乙個結點分配一此記憶體,由於沒有閒置的記憶體,鍊錶的效率比陣列高。單向鍊錶的結構可以如下表示:
struct listnode
;
那麼往鍊錶的末尾新增乙個結點的**為:
void addtotail(listnode** head,int value)
else
node->next=pnew;
}}
其中其中特別要注意的是函式的第乙個引數傳入的是指標的指標。這是因為我們在函式中有可能要改變頭結點的指向,當我們往乙個空煉表中插入結點時,新插入的結點就是鍊錶的頭指標。此時,會改變頭指標的指向,因此必須把頭指標phead引數設為指向指標的指標。補充:編譯器會為函式的引數製作乙個臨時的副本,當指標phead作為函式引數時,編譯器會自動為該指標建立乙個副本phead_,使phead和phead_指向同乙個資料,在函式中,假若這是乙個空的鍊錶,當插入第乙個結點時,會在函式的內部為phead_分配一塊記憶體,但是phead沒有任何改變,任然是乙個空指標。
鍊錶側查詢與刪除:
void removenode(listnode** head,int value)
if(pnode->value==value)
else
while(phead->next!=null)
return behindhead;
這裡需要注意幾個問題,來保證程式的魯棒性。在函式的入口處新增**以驗證使用者的輸入是否合法。
一、輸入的頭指標為空
二、輸入的k大於結點總數
三、輸入的引數k等於0或小於0,
for(int i=0;i
相似的題目:求鍊錶的中間結點,如果鍊錶中結點總數為奇數,返回中間結點;如果鍊錶中結點總數為偶數,返回中間兩個結點中的任意乙個結點。為了解決這個問題,我們也可以定義兩個指標,同時從鍊錶的頭結點出發,乙個每次走一步,另乙個每次走兩步,當走的快的指標走到鍊錶的末尾時,走的慢的指標正好在鍊錶的中間。
listnode* findmiddle(listnode*head)
return p_second;
}
反轉鍊錶:
listnode* reverselist(listnode* head)
return preversedhead;
}
總結了一下要點:
1、三個指標,當前結點的指標、當前結點的前乙個結點,當前結點的下乙個結點
2、記錄當前結點的下乙個結點
資料結構與演算法(1)陣列與鍊錶
學習極客時間資料結構與演算法之美總結 陣列是在記憶體上連續的記憶體空間。陣列隨機查詢演算法複雜度為o 1 但是插入和刪除都為o n 這個要看情況,要是資料不是按照順序的話,那麼直接把目標位置替換成新的值,然後將舊的值放到最後,這樣演算法複雜度依然為o 1 刪除的時候把刪除的地方做標記,等到空間不足的...
資料結構與演算法 鍊錶
題目 合併兩個已經排序好的鍊錶 非遞迴和遞迴兩種 方法1 cpp view plain copy print color 000000 合併鍊錶.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std struct listnod...
資料結構與演算法 鍊錶
在講述鍊錶之前讓我們對資料結構進行乙個簡單的回顧 我們知道,資料結構指的是描述實際問題中各個資料項節點之間的前後邏輯結構關係,即要麼是線性結構 即某一資料項的前繼節點和後繼節點有且只有乙個 要麼是非線性結構 即某一資料節點的前驅或者後繼節點不止乙個 在確定了實際資料項的資料結構之後,我們要採用某種儲...