1. 程式人生 > 其它 >資料結構-雙鏈表

資料結構-雙鏈表

技術標籤:資料結構資料結構指標連結串列演算法

雙鏈表

  單鏈表結點中只有一個只指向後繼的指標,使得單鏈表只能從頭結點開始一次順序的先後遍歷。要訪問某個結點的前驅結點(插入刪除操作時),只能從頭開始遍歷,訪問後繼節點的時間複雜度為O(1),訪問前驅結點的時間複雜度為O(n)。

  為了克服單鏈表的上述缺點,引入了雙鏈表,雙鏈表結點中有兩個指標prior 和 next,分別指向其前驅結點和後繼結點。

  定義

  雙鏈表中結點型別描述:

typedef struct DNode{
    ElemType data;
    struct DNode *prior, *next;
}DNode,
*DLinkList;

  在雙鏈表中,按位查詢和按值查詢的操作和單鏈表中的相同。但在插入和刪除上有著較大的不同。因為雙鏈表有prior指標,可以很方便地找到其前驅結點,因此插入,刪除結點的時間複雜度為O(1)。

  前插操作

  將結點s 插入到指標p所指結點b之前:

bool DLinkList_Insert(DLinkList& L,ElemTyep c){
    DNode* p;
    /* 先檢查位置是否合法...  */
    DNode* s = (DNode*)malloc(sizeof(DNode));
    s->data = c;
    //第一步:結點s的prior指標指向左邊的結點
s->prior = p->prior; //第二步:結點b的前驅結點(也就是左邊的結點)的next指標指向結點s p->prior->next = s; //第三步:結點s的next指標指向結點b s->next = p; //第四步:結點b的prior指標指向結點s p->prior = s; return true; }

  注意:第一,二步必須在第四步之前,否則*p的前驅結點的指標就會丟失,導致插入失敗。

  後插操作

  將結點s 插入到指標p所指的節點b 之後(如上圖,假設後面的結點是d):

bool DLinkList_Insert(DLinkList& L,ElemType c){
    DNode* p;
    DNode* s = (DNode*)malloc(sizeof(DNode));
    s->data = c;
    //第一步:將結點s 的next指標指向後繼結點
    s->next = p->next;
    //第二步;將後繼結點的prior指標指向結點s
    p->next->prior = s;
    //第三步:將結點s的prior指標指向結點b
    s->prior = p;
    //第四步:將結點b的next指標指向結點s
    p->next = s;
    return true;    
}

  同樣的,前插操作和後插其實沒區別,注意第四步即可,大家不清楚可以在草稿紙上面畫出來,畫出來了就一目瞭然了。

  刪除操作

  刪除指標p指向的結點b:

bool DLinkList_Delete(DLinkList& L){
    DNode* p;
    //第一步:將結點b的前驅結點的next指標指向結點c
    p->prior->next = p->next;
    //第二步:將結點c的prior指標指向結點b的前驅結點
    p->next->prior = p->prior;
    //釋放結點空間
    free(p);
}

  如果是刪除指標p指向的結點的後繼結點,指標q指向後繼結點,也就是後刪:

bool DLinkList_Delete(DLinkList& L){
    DNode *p,*q;
    p->next = q->next;
    q->next->prior = p;
    free(q);
}

如果覺得本文對你有幫助的話,不妨關注作者一波,小小的關注其實對我很重要。更多高質量內容與資料請訪問:資料結構簡單學,個人主頁:修心的小屋
如果喜歡的話,不妨關注一波,謝謝啦。
在這裡插入圖片描述