數據結構與算法----雙向鏈表

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

/**
 * 建立結構體
 * */
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條,但畫圖的話就看到兩條。code

如圖:blog

::|::get

 

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

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

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

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

總體插入代碼就是class

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;

若是首結點後只有一個結點im

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條指向線前後順序,若是鏈接順序不正確,斷開後的數據就會丟失。

相關文章
相關標籤/搜索