1. 程式人生 > 其它 >資料結構——雙鏈表

資料結構——雙鏈表

技術標籤:資料結構連結串列

文章目錄


一、什麼是雙鏈表

概念:在使用一個單鏈表時,我們可以通過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;
}

雙鏈表的其他操作與單鏈表類似,程式碼不再重複給出,雙鏈表在往前找這一方面還是比較方便的。