雙向鏈表

 

請使用 VC++6 打開 main.dsw 文件,然後點擊運行按鈕(就是那個紅色的歎號)編譯執行。
 
雙鏈表
線性表的插入運算(雙向鏈表存儲結構)
在雙向循環鏈表L的位置p處插入一個新元素x的過程Insert可實現如下。
 
算法:
typedef struct dnode {
       elemtype data;
       struct dnode *prior, *next;
} DNODE;

int link_ins(DNODE **head, int i, elemtype x)
{
     int j = 1; /* 雙向循環鏈表 */
     DNODE *p, *q;
     q = malloc( sizeof *p );
     q->data = x;
     if ( i == 0 ) {
         q->prior = *head;
         q->next = *head;
         *head = q;
         return 0;
     }
     p = *head;
     j = 0;
     while ( ++j < i && p != NULL )
           p = p->next;
     if ( i < 0 || j < i )
         return 1;
     else {
           q->next = p->next;
           p->next = q;
           p->next->prior = q;
           q->prior = p;
           return 0;
     }
}
分析:在上面的插入算法中,不需要移動別的元素,但必須
從頭開始查找第i結點的地址,一旦找到插入位置,則插入結點
只需兩條語句就可完成。該算法的時間複雜度爲O(n)
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、雙向鏈表的前插和刪除本結點操作
     由於雙鏈表的對稱性,在雙鏈表能能方便地完成各種插入、刪除操作。
①雙鏈表的前插操作
 
    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)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章