PS:前面已經說過線性表的兩種表現形式,一種是順序,另外一種是鏈式,鏈式的一種普通表現形式就是加入一個指針,前一個的指針指向後一個結點的地址,那麼還有一種形式就是雙向鏈表,裏面又加上了一個指針變量,讓前指針變量指向直接前驅,後指針變量指向直接後繼。spa
/** * 建立結構體 * */ typedef struct DoubleLink { int data; struct DoubleLink *prior; struct DoubleLink *next; } DoubleLink, *DoubleLinkL;
/** * 初始化 * */ 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; }