Ⅰ 雙向鏈表相比單鏈表的優勢
從結構上來看,雙向鏈表可以支持 O(1) 時間復雜度的情況下找到前驅結點,雙向鏈表在某些情況下的插入、刪除等操作都要比單鏈表簡單、高效。
你可能會說,我剛講到單鏈表的插入、刪除操作的時間復雜度已經是 O(1) 了,雙向鏈表還
能再怎麼高效呢?其實說單鏈表插入、刪除操作的時間復雜度為O(1)是不準確的,或者說是有先決條件的。
我們先來看刪除操作。
在實際的軟體開發中,從鏈表中刪除一個數據無外乎這兩種情況:
對於第一種情況,不管是單鏈表還是雙向鏈表,為了查找到值等於給定值的結點,都需要從
頭結點開始一個一個依次遍歷對比,直到找到值等於給定值的結點,然後將其刪除。
盡管單純的刪除操作時間復雜度是 O(1),但遍歷查找的時間是主要的耗時點,對應的時間復雜度為 O(n)。根據時間復雜度分析中的加法法則,刪除值等於給定值的結點對應的鏈表操作的總時間復雜度為 O(n)。
對於第二種情況,我們已經找到了要刪除的結點,但是刪除某個結點 q 需要知道其前驅結點,而單鏈表並不支持直接獲取前驅結點,所以,為了找到前驅結點,我們還是要從頭結點開始遍歷鏈表,直到 p->next=q,說明 p 是 q 的前驅結點。
但是對於雙向鏈表來說,這種情況就比較有優勢了。因為雙向鏈表中的結點已經保存了前驅結點的指針,不需要像單鏈表那樣遍歷。所以,針對第二種情況,單鏈表刪除操作需要O(n) 的時間復雜度,而雙向鏈表只需要在 O(1) 的時間復雜度內就搞定了!
同理,如果我們希望在鏈表的某個指定結點前面插入一個結點,雙向鏈表比單鏈表有很大的優勢。雙向鏈表可以在 O(1) 時間復雜度搞定,而單向鏈表需要 O(n) 的時間復雜度。
除了插入、刪除操作有優勢之外,對於一個有序鏈表,雙向鏈表的按值查詢的效率也要比單鏈表高一些。 因為,我們可以記錄上次查找的位置 p,每次查詢時,根據要查找的值與 p的大小關系,決定是往前還是往後查找,所以平均只需要查找一半的數據。
Ⅱ l數據結構~~雙鏈表的實現
雙鏈表
1、雙向鏈表(Doubly
Linked
List)
雙(向)鏈表中有兩條方向不同的鏈,即每個結點中除next域存放後繼結點地址外,還增加一個指向其直接前趨的指針域prior。
注意:
①雙鏈表由頭指針head惟一確定的。
②帶頭結點的雙鏈表的某些運算變得方便。
③將頭結點和尾結點鏈接起來,為雙(向)循環鏈表。
2、雙向鏈表的結點結構和形式描述
①結點結構(見上圖a)
②形式描述
typedef
struct
dlistnode{
DataType
data;
struct
dlistnode
*prior,*next;
}DListNode;
typedef
DListNode
*DLinkList;
DLinkList
head;
3、雙向鏈表的前插和刪除本結點操作
刻畫雙鏈表結構的對稱性的語句:p→prior→next==
p→next→prior;由於雙鏈表的對稱性,在雙鏈表能能方便地完成各種插入、刪除操作。
①雙鏈表的前插操作
void
DInsertBefore(DListNode
*p,DataType
x)
{//在帶頭結點的雙鏈表中,將值為x的新結點插入*p之前,設p≠NULL
DListNode
*s=malloc(sizeof(DListNode));//①
s->data=x;//②
s->prior=p->prior;//③
s->next=p;//④
p->prior->next=s;//⑤
p->prior=s;//⑥
}
②雙鏈表上刪除結點*p自身的操作
void
DDeleteNode(DListNode
*p)
{//在帶頭結點的雙鏈表中,刪除結點*p,設*p為非終端結點
p->prior->next=p->next;//①
p->next->prior=p->prior;//②
free(p);//③
}
注意:
與單鏈表上的插入和刪除操作不同的是,在雙鏈表中插入和刪除必須同時修改兩個方向上的指針。
上述兩個演算法的時間復雜度均為O(1)。
Ⅲ 判斷題:雙向鏈表結構比順序存儲結構在「插入」和「刪除」數據操作上更為方便。
正確。
因為雙向鏈接插入、刪除時只需要修改前後幾個節點的鏈接即可。
而順序存儲結構如數組,插入時需要將其後所有數據後移一位以騰出空位,刪除時需要將其後所有數據前移一位以消去空位。
綜上,正確。
Ⅳ 使用雙鏈表存儲數據的優點是什麼
可以在當前結點前後隨意插入刪除,插入刪除結點時間短,不必預估存儲空間,沒有空間溢出,很方便進行向後繼和向前驅的雙向遍歷
Ⅳ 說鏈表較於順序表的優勢有一個是便於插入和刪除,鏈表時間復雜度也是O(n),(若要對最後一個數進行操作
鏈表的插入和刪除之所以是o(n),是因為要用o(n)順序查找到插入點的位置,插入時間為o(n)
順序表找到插入點的時間為o(1),但要把後面的元素全部後移一位,復雜度為o(n)。
查找所需時間比移動短多了,所以雖然復雜度都是o(n),但是鏈表更適合插入刪除
Ⅵ 如果一個鏈表最常用的操作是在末尾插入節點和刪除尾節點,為什麼選用帶頭節點的雙循環鏈表最省時間
鏈表最常用的操作是在末尾插入節點和刪除尾節點,在尾巴插入 刪除操作:
都需要知道他的前導 而單鏈表要查找到最有一個元素需要遍歷全部鏈表
雙鏈表直接可以查到前導;
最常用的操作實在最後一個元素之後插入一個元素和刪除第一個元素
刪除頭結點 需要頭指針 或者只用一個->next域就能查到 速度就快了
在有第二個條件 刪除最後一個元素 有尾指針就最好了 可以直接找到尾巴元素 同時他還是循環鏈表 ->next就是頭結點。
鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操作復雜。由於不必須按順序存儲,鏈表在插入的時候可以達到O(1)的復雜度,比另一種線性表順序錶快得多,但是查找一個節點或者訪問特定編號的節點則需要O(n)的時間,而線性表和順序表相應的時間復雜度分別是O(logn)和O(1)。