鏈表是什么?
**鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比于線性表順序結構,操作復雜。由于不必須按順序存儲,鏈表在插入的時候可以達到O(1)的復雜度,比另一種線性表順序表快得多,但是查找一個節點或者訪問特定編號的節點則需要O(n)的時間,而線性表和順序表相應的時間復雜度分別是O(logn)和O(1)。
使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。但是鏈表失去了數組隨機讀取的優點,同時鏈表由于增加了結點的指針域,空間開銷比較大。鏈表最明顯的好處就是,常規數組排列關聯項目的方式可能不同于這些數據項目在記憶體或磁盤上順序,數據的存取往往要在不同的排列順序中轉換。鏈表允許插入和移除表上任意位置上的節點,但是不允許隨機存取。鏈表有很多種不同的類型:單向鏈表,雙向鏈表以及循環鏈表。鏈表可以在多種編程語言中實現。像Lisp和Scheme這樣的語言的內建數據類型中就包含了鏈表的存取和操作。程序語言或面向對象語言,如C,C++和Java依靠易變工具來生成鏈表。**
鏈表基礎操作
首先我們要想,一個結點里面要有什么?
一個是數據域,第二個是指針域,指向下一個結點,所以我們用一個結構體來包括一個結點所需要的這些內容。
這是鏈表中的一個結點的內容
SListDataType這個類型,是用戶自定義類型,可以是int ,double,char,還可以是一個結構體類型。
而這個結構體里,就是鏈表的創建,里面是第一個結點的指針。
初始化,首先傳一個鏈表的結構體指針,第一步判斷指針是否為空,此處用斷言判斷,第二步初始化,給第一結點指空。
頭插,時間復雜度為O(1),傳進來連邊的結構體指針,和要給結點里附的值。
一 創建新結點。二新的結點里的數據域里附傳進來的值三新建結點的指針域指向第一個結點四第一個結點指向新建結點,讓新建結點作為新的鏈表的第一個結點
尾插,有循環,O(n)
一,創建新結點,新結點數據域賦值,新結點指針域指控。
二,判斷鏈表是否為空,如果為空,把讓鏈表的第一個結點指針指向新建的結點。
三,找最后一個結點,隱藏著鏈表一定有結點,創建一個新指針指向鏈表第一個結點,當指針不為空時,指針往后移。循環結束后,最后一個結點的指針域指向新建結點
頭刪
一,首先判斷,如果沒有鏈表,沒有結點不能刪。
二 新建指針指向第一個結點的下一個結點.
三 釋放第一個結點。
四 第一個結點指向新建指針。
尾刪 O(n)
一,首先判斷第一個結點 assert(s != NULL); // 不能沒有鏈表assert(s->first != NULL); 不能沒有結點二,如果鏈表中只有一個結點,直接釋放三,否則,創建新指針指向頭結點,**當下下一個結點不為空,指針指向下一個。釋放下一個結點**,最后指空
查找
一 遍歷鏈表,找到數據域里的值相同時,返回。
刪除多個值相同的結點
一判斷是否為空
二 判斷是否只為一個結點
三 創建新指針cur指向第一個結點,當該結點下一個不為空時,如果結點下一個的數據域里的值等于要刪的值,創建新指針指向下下一個結點
四 然后釋放當前結點,并讓cur指向下一個結點。