資料結構——雙鏈表
阿新 • • 發佈:2021-01-31
文章目錄
一、什麼是雙鏈表
概念:在使用一個單鏈表時,我們可以通過next指標很輕鬆地訪問下一個結點,但是如果想要找到一個結點的前驅結點卻沒有什麼好的辦法,只能從頭開始遍歷。既然我們想要很輕鬆地訪問前驅結點,那麼定義一個像next一樣的指標指向前驅結點不就好了嗎!確實如此,這樣每個結點都有兩個指標域,分別指向前驅結點和後繼結點,這樣的連結串列就是雙鏈表。
程式碼:
typedef struct DNode
{
ElemType data;
struct DNode * prior, *next; //前驅結點指標,後繼結點指標
}DNode, *DLinkList;
二、雙鏈表的操作
1.初始化
①帶頭結點
bool InitDLinkList(DLinkList &L)
{
L = new DNode; //建立一個頭結點並分配空間
if (L == NULL)
return false; //記憶體不足分配失敗
L->prior = NULL; //頭結點的prior指標永遠指向NULL
L->next = NULL; //頭結點後面暫時還沒有結點
return true;
}
②不帶頭結點
bool InitDLinkList(DLinkList & L)
{
L = NULL;
return true;
}
2.判空
bool Empty(DLinkList L)
{
if (L->next ==NULL)
return true;
else
return false;
}
3.插入
bool InsertNextDNode(DNode* p, DNode* s)
{//在給定p結點後插入一個結點s
if (p == NULL || s == NULL)
return false; //傳入的結點有錯誤
s->next = p->next; //新結點的後繼結點指向p結點的後繼結點
if (p-> next != NULL) //如果p結點不是最後一個結點
P->next->prior = s; //p的後繼結點的前驅指標指向新結點
s->prior = p; //新結點的前驅指標指向前驅結點p
p->next = s; //p結點的後繼指標指向新結點,這一步要放在最後寫
return true;
}
上述程式碼是一個結點的後插操作,得益於雙鏈表有兩個指標,所以其他的插入操作比如前插操作,按位序插入等都可以在後插的基礎上很輕鬆地完成。
4.刪除
bool DeleteNextDNode(DNode* p)
{//刪除結點p的後繼結點
if (p == NULL)
return false; //傳入的結點有誤
DNode* q = p->next; //令q指向p的後繼結點
if (q == NULL)
return false; //p沒有後繼結點
p->next = q->next; //把要刪除的結點的下一個結點接在p結點後面
if (q->next != NULL) //如果要刪除的結點不是最後一個結點
q->next->prior = p;
delete q; //釋放被刪除結點中的資料
return true;
}
其他刪除操作例如按位序刪除,也可以藉助上述程式碼完成。
5.銷燬
bool DestoryList(DLinkList &L)
{//迴圈釋放各個資料結點
while (L->next != NULL)
DeleteNextDNode(L);
delete L;
L->NULL;
return true;
}
雙鏈表的其他操作與單鏈表類似,程式碼不再重複給出,雙鏈表在往前找這一方面還是比較方便的。