雙向連結串列圖解(前插操作,刪除操作)
雙向連結串列
迴圈單鏈表的出現,雖然能夠實現從任一結點出發沿著鏈能找到其前驅結點,但時間耗費是O(n)。如果希望從表中快速確定某一個結點的前驅,另一個解決方法就是在單鏈表的每個結點裡再增加一個指向其前驅的指標域prior。這樣形成的連結串列中就有兩條方向不同的鏈,我們可稱之為雙(向)連結串列(Double Linked List)。雙鏈表的結構定義如下:
typedef struct DNode { ElemType data; struct DNode *prior,*next; }DNode,*DoubleList; |
雙鏈表的結點結構如圖2.14所示。
與單鏈表類似,雙鏈表一般也是有頭指標唯一確定的,增加頭結點也能使雙鏈表的某些運算變得方便。同時雙向連結串列也可以有迴圈表,稱為雙向迴圈連結串列,其結構如圖2.15
由於在雙向連結串列中既有前向鏈又有後向鏈,尋找任一個結點的直接前驅結點與直接後繼結點變得非常方便。設指標p指向雙鏈表中某一結點,則有下式成立:
P->prior->next=p=p->next->prior |
在雙向連結串列中,那些只涉及後繼指標的演算法,如求表長度、取元素、元素定位等,與單鏈表中相應的演算法相同,但對於前插和刪除操作則涉及到前驅和後繼兩個方向的指標變化,因此與單鏈表中的演算法不同。
1.雙向連結串列的前插操作
演算法描述:欲在雙向連結串列第i個結點之前插入一個新的結點,則指標的變化情況如圖2.16所示。
int DlinkIns(DoubleList L,int i,ElemType e) { DNode *s,*p; …/*先檢查待插入的位置i是否合法(實現方法同單鏈表的前插操作)*/ …/*若位置i合法,則讓指標p指向它*/ s=(DNode *)malloc(sizeof(DNode)); if(s) { s->data=e; s->prior=p->prior;p->prior->next=s; s->next=p;p->prior=s; return TRUE; } else teturn fALSE; } 演算法雙向連結串列的插入操作 |
2.雙向連結串列的刪除操作
演算法描述
int DlinkDel(DoubleList L,int i,ElemType *e)
{
DNode *p;
…/*首先檢查待插入的位置i是否合法(實現方法同單鏈表的刪除操作)*/
…/*若位置i合法,則讓指標p指向它*/
*e=p->prior->next=p->next;
p->next->prior->p=p->prior;
free(p);
return TRUE;
}