陣列insert 陣列實現單鏈表

2021-10-11 16:07:32 字數 2717 閱讀 5394

單鏈表常見的實現方法有兩種,一種方式是定義乙個結構體表示鍊錶節點。比如:

struct node;
然後就是通過next指標將鍊錶的所有節點連線起來。如果涉及到鍊錶節點的插入和刪除操作,則只需要修改鍊錶節點的指標即可。

這種方式有個明顯的缺點,就是不能隨機訪問。如果要在某個節點之後插入或者刪除節點,複雜度是o(n),因為要從頭開始逐個遍歷到需要插入或者刪除的節點(通過next指標找)。所以用結構體實現的單鏈表缺點就是太慢了。當然還有乙個原因就是c++裡要new乙個node比較慢。總之就是慢~

因此演算法題中使用單鏈表往往是通過陣列實現,陣列實現的單鏈表可以通過下標來索引節點,可以直接通過下標找到某個節點的值和下乙個節點的,因此陣列實現的單鏈表的最大優點就是快(插入和刪除操作都是o(1)的時間複雜度),畢竟陣列的特點就是隨機訪問嘛。

這裡結合一道題目來看陣列實現單鏈表。 原題鏈結

這道題題意非常直白。就是需要實現乙個單鏈表,這個鍊錶支援三個操作:(1)在鍊錶的表頭插入乙個節點;(2)刪除某個數後面的數;(3)在某個數後面加入乙個數(即插入節點)。 輸入有若干行,每行都有可能是三個操作的其中之一,最後的輸出就是經過所有操作之後從頭到尾將鍊錶輸出。

來模擬一下樣例吧。

來看一下實現。 要實現三個操作,我們可以額外定義三個函式分別表示上面三個操作。 這裡分別命名為insertbeforehead(int x)insert(int k, int x)delete(int k)。這裡的x就是要插入的值,k就是要插入/刪除節點的前乙個位置(也就是在第k個節點之後進行插入/刪除)。

這裡要注意,第k個節點並不是當前鍊錶從前往後數,而是從最開始計算,插入的第k個節點(也就是說前面插入的節點被刪除了,並不會重新計算k)。

要用陣列表示單鏈表,和結構體實現鍊錶一樣,每個節點都要有值和記錄下乙個節點的「指標」,因此我們可以開兩個陣列val和nex分別表示節點的數值和下乙個節點的位置。 由於需要對鍊表頭做操作(在煉表頭插入節點)和記錄已經插入的節點的個數(因為要在第k個節點之後進行插入/刪除操作),因此我們需要用兩個「指標」記錄頭節點和當前操作的節點是第幾個節點。 簡單的說,head指向的就是煉表頭節點(第乙個節點,不是附加頭節點)的下標,idx表示當前用到的是第幾個節點。

const int n = 1e5 + 5;

int val[n], nex[n], head, idx; //head表示頭節點的下標,idx表示已經插入的節點的個數

鍊錶需要有初始化操作,不然headidx的值可能是不確定的。

void init()
然後看一下在煉表頭節點(之前)插入節點。 由於head記錄了原來的頭節點,我們希望新插入乙個節點,這個節點的值為x,且這個節點的**next指標**指向原來的head。 看一下**:

void insertbeforehead(int x)
看一下如何在第k個節點之後插入乙個節點。 首先肯定要建立乙個值為x的節點:val[idx] = x;且這個新節點的next指標指向第k+1個節點:nex[idx] = nex[k]. (nex[k]是原來的第k+1個節點,讓新插入的節點指向這個節點)。 然後k的next指標也要更新,指向x:nex[k] = idx;再更新一下已經插入的節點的個數:++idx;這樣就得到在第k個節點之後插入節點x的**:

void insert(int k, int x)
然後就剩下在第k個節點之後刪除節點的函式啦: 這個很簡單,要讓第k個節點之後的值不存在,就直接讓第k個節點的next指標指向第k+2個節點,也就是跳過了第k+1個節點,這樣第k+1個節點就社會性死亡了。

void delete(int k)
這道題的完整**如下:

#includeusing namespace std;

const int n = 1e5 + 5;

int val[n], nex[n], head, idx;

void init()

void insertbeforehead(int x)

//在下標為k的節點後插入x

void insert(int k, int x)

//刪除下標為k的節點的下乙個節點

void delete(int k)

int main() else if(op == 'i') else if(op == 'd') else }}

for(int i = head; i != -1; i = nex[i])

cout << endl;

return 0;

}

單鏈表的陣列實現

解決圖 和樹的存 儲問題。解決圖和樹的儲存問題。解決圖和樹的 儲存問題 題目 實現乙個單鏈表,鍊錶初始為空,支援三種操作 1 向煉表頭插入乙個數 2 刪除第k個插入的數後面的數 3 在第k個插入的數後插入乙個數 現在要對該鍊錶進行m次操作,進行完所有操作後,從頭到尾輸出整個鍊錶。注意 題目中第k個插...

演算法( 單鏈表(以陣列實現))

用陣列模擬鍊錶,速度快 相當於靜態鍊錶 實現乙個單鏈表,鍊錶初始為空,支援三種操作 1 向煉表頭插入乙個數 2 刪除第k個插入的數後面的數 3 在第k個插入的數後插入乙個數 現在要對該鍊錶進行m次操作,進行完所有操作後,從頭到尾輸出整個鍊錶。注意 題目中第k個插入的數並不是指當前鍊錶的第k個數。例如...

陣列VS單鏈表

陣列需要一塊連續的記憶體空間來儲存,對記憶體的要求比較高。鍊錶恰恰相反,它並不需要一塊連續的記憶體空間,它通過 指標 將一組零散的記憶體塊串聯起來使用。如果我們申請乙個 100mb 大小的陣列,當記憶體中沒有連續的 足夠大的儲存空間時,即便記憶體的剩餘總可用空間大於 100mb,仍然會申請失敗。如果...