鍊錶知識點總結(一) 鍊錶的常見操作以及複雜度分析

2021-09-28 23:26:00 字數 2408 閱讀 8506

鍊錶是資料結構中最基礎的鏈式結構,也是後面構成圖、樹的基礎。為此,我覺得有必要專門開幾篇文章寫寫鍊錶相關的內容,但是如果從零開始寫起太過於枯燥,文章也會變得冗長,所以本文只寫一些總結性的內容,對其中的原理不深究。

class node

};

下文**現的checkindex函式為檢查索引引數是否合法的函式,本來是用於我的封裝鍊錶中的(封裝的鍊錶中還有乙個size成員,可以知道鍊錶的長度,以此來判斷索引是否合法),具體實現這裡就不給出了,這裡預設傳入的引數都是合法的、且鍊錶為非空鍊錶,忽略這個函式呼叫即可。

下面總結一些我個人的鍊錶常見操作的實現,並且會帶上簡單的複雜度分析。以下實現預設是對帶頭節點的單鏈表進行的操作

void delll(node *header)

}

以一前一後兩個指標pre和cur掃鍊錶,不斷讓兩個指標後移,同時刪除pre所指的節點,直到cur指向null為止。凡是需要用兩個指標掃鍊錶的操作都建議根據實際用途命名為pre 和 cur,代表前乙個節點和當前指向節點。時間複雜度為o(n),由於需要對鍊錶進行遍歷,所以是on。

void add(node* header, int data, int index)

pre->next = new node(data, pre->next);

}

這裡我預設傳進來的index為從1開始的索引,所以for的中止條件需要-1,實現思路是用pre指標掃鍊錶,先找到要插入位置的前乙個個節點,然後再讓新節點成為pre指向節點的下乙個節點,注意,此時pre後面可能還有節點,要把pre節點的next賦值給新節點的next,就把要插入的節點插入進去了,這裡使用了node類的乙個建構函式,讓**變得簡潔。

另外,給鍊錶新增頭節點的好處也在這裡體現,試想一下,如果沒有頭節點的話,那麼add函式就得判斷一下當前要插入的位置是否是第乙個位置,是的話就得修改header指標,不是的話就進入上面add函式裡的迴圈,去找待插入位置的前乙個節點。但是我們給鍊錶加入頭結點後,不管插入的是不是第乙個位置,我們都不需要修改header指標,也就是不需要額外的if來判斷,這樣就簡化了**。

時間複雜度為o(n),從頭部插入的話是o1的複雜度,但是插入到其他地方的話就就是on,所以不管是從最壞的角度考慮,還是從綜合的角度考慮,其時間複雜度都為on。

上面講的是在任意位置的插入,其實就是教科書裡說的尾插法,下面說說頭插法。

頭插法,顧名思義,就是在鍊錶的頭部插入乙個元素,如果對乙個鍊錶一直使用頭插法插入元素的話,將會得到跟插入順序倒序的鍊錶。**:

void headinsertion(node *header, int data)

如果是按照我上面節點定義的那樣定義了建構函式的話,其實可以這樣寫:

void headinsertion(node *header, int data)

對頭插法來說,時間複雜度是o(1)的,因為它不需要遍歷整個鍊錶。

int remove(node* header, int index)

node *tmp = pre->next;

pre->next = tmp->next;

int res = tmp->data;

delete tmp;

return res;

}

這裡也是跟插入一樣,先找到要刪除節點的上乙個節點,因為要返回這個要刪除節點的值,所以得先用臨時變數res把data存起來後面返回,又因為要把這個要刪除節點的記憶體釋放,所以還得用乙個臨時指標tmp儲存這個要刪除節點。時間複雜度為o(n),分析同單鏈表的插入。

void print(node* header)

cout << endl;

}

這裡以輸出整個鍊錶為例,用cur指標掃一遍鍊錶即可,要注意,cur初始值應為第乙個資料節點,而不是頭節點。時間複雜度o(n),遍歷嘛,肯定是和鍊錶的長度n有關。

void reverse(node *header)

}

這裡其實就是從第乙個資料節點開始,將節點逐個用頭插法插入到原煉表中(頭節點),就完成了反轉操作,顯然,這個操作的時間複雜度也是o(n)

單鏈表的各種操作都不難理解,對初學者而言,需要多理解各種操作的實現原理,必要時在草稿紙上畫草圖梳理下思路,在理解各種操作的原理後最好動手打幾遍單鏈表的完整實現,這樣才能真正掌握學到的知識點。總之,多看,多想,多寫。

資料結構 鍊錶 鍊錶00 鍊錶知識點總結

鍊錶是一種動態結構,建立鍊錶時,無須知道鍊錶長度,插入乙個節點時,只需為新節點分配記憶體,然後調整指標。struct listnode void insertnode listnode phead,int data phead頭指標 else 鍊錶記憶體不是連續的,所以找第i個節點時,需要從開頭遍歷...

關於鍊錶的知識點

宣告新的型別名來代替原有的型別名 比如,typedef int interger 或 typedef float real 相當於用interger來代表int型別,用real來代表float 習慣上把用typedef宣告的型別用大寫字母表示 1 以下語句宣告了了乙個名為 ptrtonode 的型別...

C 鍊錶操作總結和常見鍊錶操作

一 鍊錶的定義 鍊錶是一種動態資料結構,他的特點是用一組任意的儲存單元 可以是連續的,也可以是不連續的 存放資料元素。鍊錶中每乙個元素成為 結點 每乙個結點都是由資料域和指標域組成的,每個結點中的指標域指向下乙個結點。head是 頭指標 表示鍊錶的開始,用來指向第乙個結點,而最後乙個指標的指標域為n...