1. 程式人生 > >資料結構與演算法----雙向連結串列

資料結構與演算法----雙向連結串列

PS:前面已經說過線性表的兩種表現形式,一種是順序,另一種是鏈式,鏈式的一種普通表現形式就是加入一個指標,前一個的指標指向後一個結點的地址,那麼還有一種形式就是雙向連結串列,裡面又加上了一個指標變數,讓前指標變數指向直接前驅,後指標變數指向直接後繼。

/**
 * 建立結構體
 * */
typedef struct DoubleLink {
    int data;
    struct DoubleLink *prior;
    struct DoubleLink *next;
} DoubleLink, *DoubleLinkL;

建立雙向連結串列並初始化

注:這裡我們是隻建立了一個空的連結串列,內部無資料,所以首結點的兩個指標變數要為NULL。

/**
 * 初始化
 * */
DoubleLinkL initLink() {
    DoubleLinkL L = (DoubleLinkL) malloc(sizeof(DoubleLink));
    L->next = NULL;
    L->prior = NULL;
    return L;
}

開始插入資料

在插入資料之前我們要考慮一個事情就是,連結串列中有資料和無資料的插入是否一樣,也就是說指標改變是否一致,在左右都有值的時候平時要改變4條線,那麼如果只有首結點的話移動幾條呢。

其實可以說是移動3條,但畫圖的話就看到兩條。

如圖:

::|::

首先當只要一個首結點或者在最後一個結點插入的情況下,如第一個圖,

     s->next = p->next;
        s->prior = p;
        p->next = s;

當前後都有結點的時候,如第二個圖

     s->next = p->next;
        s->prior = p;
        p->next = s;
        s->next->prior = s;

整體插入程式碼就是

int insertLink(DoubleLinkL &L, int pos, int e) {
    DoubleLinkL p = L;
    
int i = 0; while (p && i < pos-1) { p = p->next; i++; } if (!p || i > pos-1) { printf("插入失敗,下標問題\n"); return -1; } DoubleLinkL s = (DoubleLinkL) malloc(sizeof(DoubleLink)); s->data = e; if (p->next == NULL) { s->next = p->next; s->prior = p; p->next = s; } else { s->next = p->next; s->prior = p; p->next = s; s->next->prior = s; } return 0; }

刪除圖解

對於刪除比較簡單,在前後都有結點的情況下,如圖一,如果本來只要一個結點,前面是首結點的情況下,直接把首結點的next指向NULL即可。(本人畫圖不怎麼樣不要在意)

p->next->next->prior=p;//一定要寫在該位置。
p->next=p->next->next;

如果首結點後只有一個結點

p->next=NULL;

刪除全部程式碼

int deleteLink(DoubleLinkL &L,int pos,int e){
    DoubleLinkL p = L;
    int i = 0;
    while (p && i < pos-1) {
        p = p->next;
        i++;
    }
    if (!p || i > pos-1) {
        printf("插入失敗,下標問題\n");
        return -1;
    }
    if(p->next==NULL){
        p->next=NULL;
    }else{
        p->next->next->prior=p;//一定要寫在該位置。
        p->next=p->next->next;
    }
    return 0;
 }

修改和查詢

這個修改和查詢是比較簡單的,直接找到知道該結點修改就完事了,幹就對了。

 int getElem(DoubleLinkL L,int pos){
     DoubleLinkL p = L;
     int i = 0;
     while (p && i < pos) {
         p = p->next;
         i++;
     }
     if (!p || i > pos) {
         printf("查詢失敗,下標問題\n");
         return -1;
     }
     printf("查詢的資料:%d\n",p->data);
     return 0;
 }
 int updataLink(DoubleLinkL &L,int pos,int e){
     DoubleLinkL p = L;
     int i = 0;
     while (p && i < pos) {
         p = p->next;
         i++;
     }
     if (!p || i > pos) {
         printf("修改失敗,下標問題\n");
         return -1;
     }
     p->data=e;
     return 0;
 }

總結:雙向連結串列主要是插入和刪除複雜點,其他的和單鏈表都差不多,雙向連結串列存在著4條指向線先後順序,如果連線順序不正確,斷開後的資料就會丟失。