数据结构--C++双链表

双链表的实现与单链表其实差不太多,只不过在双链表中,除了首尾结点,每个结点都有一个前驱和一个后继结点,本篇只谈论简单的实现双链表的基本功能,回了之后其实在向别的地方拓展也很容易了。

//created by kong 2020-03-29
#include<iostream>
using namespace std;

template <typename T>
struct DLinkList{          //双链表结点类型
	T data;				   //存放数据元素	
	DLinkList<T>* prior;   //指向前一个结点的域
	DLinkList<T>* next;	   //指向下一个结点的域
};

template<typename T>
class DLinkListClass{			//双链表类模板
	DLinkList<T>* dhead;		//双链表头结点指针
public:
	DLinkListClass<T>();			//构造函数,构建一个空的双链表
	~DLinkListClass<T>();			//析构函数,销毁双链表
	void CreateListF(T a[], int n); //采用头插法建立双链表
	void CreateListR(T a[], int n); //采用尾插法建立双链表
	void DispList();				//输出双链表的所有结点值
	int ListLength();				//求出双链表中结点个数
	int GetElem(int i);		        //求双链表中某个数据元素值
	int LocateElem(T e);			//按元素查找
	bool ListInsert(int i, T e);	//插入数据元素
	bool ListDelete(int i);			//删除数据元素
};

template<typename T>
void DLinkListClass<T>::CreateListF(T a[], int n) {     //采用头插法建立数据结点
	DLinkList<T>* s;
	int i;
	for(i=0;i<n;i++){			  //循环建立数据结点
		s = new DLinkList<T>();
		s->data = a[i];           //创建数据结点*s
		s->next = dhead->next;    //将*s插入到开始结点之前、头结点之后
		if (dhead->next != NULL)
			dhead->next->prior = s;
		dhead->next = s;
		s->prior = dhead;
	}
}

template<typename T>
void DLinkListClass<T>::CreateListR(T a[],int n){      //采用尾插法建立双链表
	DLinkList<T>* s, * r;
	int i;
	r = dhead;					 //r始终指向尾结点,开始时指向头结点
	for(i=0;i<n;i++){            //循环建立数据结点
		s = new DLinkList<T>();
		s->data = a[i];          //创建数据结点*s
		r->next = s;			 //将*s结点插入到r结点之后
		s->prior = r;
		r = s;
	}
	r->next = NULL;
}

template<typename T>
DLinkListClass<T>::DLinkListClass<T>() {   //构造函数,创建一个空的双链表
	dhead = new DLinkList<T>();
	dhead->next = NULL;
}

template<typename T>
DLinkListClass<T>::~DLinkListClass<T>() {	//析构函数,销毁双链表
	DLinkList<T>* pre, * p;
	pre = dhead; p = pre->next;              //pre指向头结点,p指向其后继结点
	while (p != NULL) {
		delete pre;                         //释放前一个结点
		pre = p; p = p->next;               //pre、p同步后移
	}
	delete pre;								//当p=NULL时,pre指向尾结点,且需要释放尾结点
	cout << "LinkList Destructing..." << endl;
}

template<typename T>
void DLinkListClass<T>::DispList() {        //输出链表所有结点值
	DLinkList<T>* p;
	p = dhead->next;						//p指向开始结点
	cout << "链表元素为:";
	while (p != NULL) {
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

template<typename T>
int DLinkListClass<T>::ListLength() {    //求双链表中数据结点个数
	int i = 0; DLinkList<T>* p;
	p = dhead;
	while (p->next != NULL) {
		i++;
		p = p->next;
	}
	return (i);							//循环结束,p指向尾结点,序号i为结点个数
}

template<typename T>
int DLinkListClass<T>::GetElem(int i) {//求单链表中某个数据元素值
	int j = 0;
	DLinkList<T>* p;
	p = dhead;       //p指向头结点,j置为0
	while (j < i && p != NULL) {
		j++;
		p = p->next;
	}
	if (p == NULL)           //不存在这个结点,返回false
		return false;
	else {                   //存在,返回结点元素值
		return  p->data;
	}
}

template<typename T>
int DLinkListClass<T>::LocateElem(T e) {    //按元素查找
	int i = 1;
	DLinkList<T>* p;
	p = dhead->next;                     //p指向开始结点,i置为1
	while (p != NULL && p->data != e) {    //查找data值为e的结点*p,序号为i
		p = p->next;
		i++;
	}
	if (p == NULL)
		return 0;        //不存在返回0
	else
		return i;        //存在返回其逻辑序号i
}

template<typename T>
bool DLinkListClass<T>::ListInsert(int i,T e){    //插入数据元素
	int j = 0;
	DLinkList<T>* s, * p = dhead;        //p指向头结点,j设置为0
	while(j<i-1&&p!=NULL){               //查找第i-1个结果
		j++;
		p = p->next;
	}
	if (p == NULL) return false;         //未找到第i-1个结点,返回false
	else {								 //找到第i-1个结点*p,在其后插入新结点*s
		s = new DLinkList<T>();			 
		s->data = e;                     //创建新结点*s
		s->next = p->next;               //在*p后插入*s结点
		if (p->next != NULL)
			p->next->prior = s;
		s->prior = p;
		p->next = s;
		return true;
	}
}

template<typename T>
bool DLinkListClass<T>::ListDelete(int i){        //删除数据元素
	int j = 0;							//p指向头结点,j设置为0
	DLinkList<T>* p = dhead, * q;
	while(j<i-1&&p!=NULL){				//查找第i-1个结点
		j++;
		p = p->next;
	}
	if (p == NULL) return false;        //未找到第i-1个结点
	else{								//找到第i-1个结点
		q = p->next;					//q指向第i个结点
		if (q == NULL) return false;	//当不存在第i个结点时返回false
		p->next = q->next;				//从双链表中删除*q结点
		if (p->next != NULL)			//若*p结点存在后继结点,修改其前驱元素
			p->next->prior = p;			
		delete q;						//释放*q结点
		return true;
	}		
}

int main() {
	int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	DLinkListClass<int> l1;
	l1.CreateListF(a, 10); l1.DispList();
	l1.CreateListR(a, 10);l1.DispList();
	cout << l1.ListLength() << endl;
	cout << l1.GetElem(5) << endl;
	cout << l1.LocateElem(7) << endl;
	l1.ListInsert(3, 11); l1.DispList();
	l1.ListDelete(7); l1.DispList();

	return 0;
}

运行结果:

当你熟练掌握了C++的基本语法后,其实学习数据结构是很简单的,一定要自己多写,加油!!

猜你喜欢

转载自blog.csdn.net/MARS_098/article/details/105185372