1. 程式人生 > >C++ 雙鏈表

C++ 雙鏈表

一、什麼是雙鏈表

雙向連結串列也叫雙鏈表,是連結串列的一種,它的每個資料結點中都有兩個指標,分別指向直接後繼和直接前驅。所以,從雙向連結串列中的任意一個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。一般我們都構造雙向迴圈連結串列。 在這裡插入圖片描述 在這裡插入圖片描述

二、雙鏈表的基本操作

建立、遍歷、測長、插入、刪除

#include <iostream>
#include <stdio.h>
using namespace std;


//結點類
class Node {
public:
	int data;
	Node *pPre, *pNext;
};

//雙向連結串列類
class DoubleLinkList {
public:
	DoubleLinkList() {
		head = new Node;
		head->data = 0;
		head->pNext = NULL;
		head->pPre = NULL;
	}
	~DoubleLinkList() { delete head; }
	void CreateLinkList(int n);				//建立連結串列
	void InsertNode(int position, int d);	//在指定位置處插入結點
	void TraverseLinkList();				//遍歷連結串列
	bool IsEmpty();							//判斷連結串列是否為空
	int GetLength();						//獲得連結串列長度
	void DeleteNode(int position);			//刪除指定位置處結點
	void DeleteLinkList();					//刪除連結串列
private:
	Node *head;
};

void DoubleLinkList::CreateLinkList(int n) {
	if (n < 0) {
		cout << "輸入結點個數錯誤!" << endl;
		exit(EXIT_FAILURE);
	}
	else {
		int i = 0;
		Node *pnew, *ptemp;
		ptemp = head;
		i = n;
		while (n-- > 0) {
			cout << "請輸入第" << i - n << "個結點值:";
			pnew = new Node;
			cin >> pnew->data;
			pnew->pNext = NULL;   //也可以放while外,但需要初始化
			pnew->pPre = ptemp;
			ptemp->pNext = pnew;
			ptemp = pnew;
		}
	}
}

void DoubleLinkList::InsertNode(int position, int d) {
	if (position < 0 || position > GetLength() + 1) {
		cout << "輸入位置錯誤!" << endl;
		exit(EXIT_FAILURE);
	}
	else {
		Node *pnew, *ptemp;
		pnew = new Node;
		pnew->data = d;
		ptemp = head;

		while (position-- > 1)
			ptemp = ptemp->pNext;

		if (ptemp->pNext != NULL)
			ptemp->pNext->pPre = pnew;
		pnew->pNext = ptemp->pNext;
		pnew->pPre = ptemp;
		ptemp->pNext = pnew;
		ptemp = pnew;
	}
}

void DoubleLinkList::TraverseLinkList() {
	Node *ptemp = head->pNext;
	while (ptemp != NULL) {
		cout << ptemp->data << " ";
		ptemp = ptemp->pNext;
	}
	cout << endl;
}

bool DoubleLinkList::IsEmpty() {
	if (head->pNext == NULL)
		return true;
	else
		return false;
}

int DoubleLinkList::GetLength() {
	int n = 0;
	Node *ptemp = head->pNext;
	while (ptemp != NULL) {
		n++;
		ptemp = ptemp->pNext;
	}
	return n;
}

void DoubleLinkList::DeleteNode(int position) {
	if (position < 0 || position > GetLength()) {
		cout << "輸入資料錯誤!" << endl;
		exit(EXIT_FAILURE);
	}
	else {
		Node *pdelete, *ptemp;
		ptemp = head;

		while (position-- > 1)
			ptemp = ptemp->pNext;
		pdelete = ptemp->pNext;
		if (pdelete->pNext != NULL)
			pdelete->pNext->pPre = ptemp;
		ptemp->pNext = pdelete->pNext;
		delete pdelete;
		pdelete = NULL;
	}
}

void DoubleLinkList::DeleteLinkList() {
	Node *pdelete, *ptemp;
	pdelete = head->pNext;
	while (pdelete != NULL) {
		ptemp = pdelete->pNext;
		head->pNext = ptemp;
		if (ptemp != NULL)
			ptemp->pPre = head;
		delete pdelete;
		pdelete = ptemp;
	}
}

//測試函式
int main() {
	DoubleLinkList dl;
	int position = 0, value = 0, n = 0;
	bool flag = false;

	cout << "請輸入需要建立雙向連結串列的結點個數:";
	cin >> n;
	dl.CreateLinkList(n);

	cout << "列印連結串列值如下:";
	dl.TraverseLinkList();

	cout << "請輸入插入結點的位置和值:";
	cin >> position >> value;
	dl.InsertNode(position, value);

	cout << "列印連結串列值如下:";
	dl.TraverseLinkList();

	cout << "請輸入要刪除結點的位置:";
	cin >> position;
	dl.DeleteNode(position);

	cout << "列印連結串列值如下:";
	dl.TraverseLinkList();

	dl.DeleteLinkList();
	flag = dl.IsEmpty();
	if (flag)
		cout << "刪除連結串列成功!" << endl;
	else
		cout << "刪除連結串列失敗!" << endl;

	system("pause");
	return 0;
}