线性表之循环双链表


    在循环链表中,虽然从任一结点出发均可以扫描到其他结点,但是要找到其前驱结点则需要遍历整个链表。如果希望快速确定表中任一结点的前驱结点,可以再每个结点中再设置一个指向其前驱结点的指针域,这样就形成的双链表(doubly linked list),如第一张图所示,prior为前驱指针域,next为后继指针域。

   结点的C++描述为:

template<class Type>
struct DulNode
{
	Type data;																		//数据域
	DulNode<Type> *prior, *next;	        //指向前驱结点的指针和指向后继结点的指针
};

    和单链表类似,双链表一般也是由头指针唯一确定,增加头结点也能使双链表的某些操作变得方便,将头结点和尾结点链接起来就构成了循环双链表,这样无论是插入还是删除操作,对链表中开始结点、终端结点和中间结点的操作过程相同。实际上常用带头结点的循环双链表,实现如下:

dullinklist类的声明:

template<class Type>
class Dullist{
private:
	DulNode<Type>* first;																//头指针指向头结点
public:
	Dullist();																	//显示默认构造函数
	Dullist(Type a [], int len);	//构造函数
	~Dullist();			//析构函数
	int getLength();		//求双链表的长度
	Type Get(int i);		//按位查找数据
	int Locate(Type x);		//按值查找数据位置
	void Insert(int i, Type x);	//在线性表第i个位置上插入值为x的结点
	Type Delete(int i);		//删除第i个元素
	void Print();			//遍历循环双链表
	bool isEqual();			//判断循环双链表是否是对称
																			
};

类实现:

template<class Type>
Dullist<Type>::Dullist(){
	first = new DulNode<Type>;
	first->next = first;
	first->prior = first;
}

template<class Type>
Dullist<Type>::Dullist(Type a [], int len){
	first = new DulNode<Type>;
	first->next = first;
	first->prior = first;
	DulNode<Type>* r = first;
	for (int i = 0; i < len; i++){
		DulNode<Type>* s = new DulNode<Type>;
		s->data = a[i];
		r->next = s;
		s->prior = r;
		r = s;
	}
	r->next = first;
	first->prior = r;
}

template<class Type>
Dullist<Type>::~Dullist(){
	int len = getLength();
	DulNode<Type>* p = first;
	while (len+1){
		p = first;
		first = first->next;
		delete p;
		len--;
	}
}

template<class Type>
int Dullist<Type>::getLength(){
	int count = 0;
	DulNode<Type>* p = first->next;
	while (p != first){
		count++;
		p = p->next;
	}
	return count;
}

template<class Type>
void Dullist<Type>::Print(){
	cout<< "头结点";
	DulNode<Type>* p =first->next;
	while (p != first){
		cout << "-->" << p->data;
		p = p->next;
	}
	cout << "-->头结点" << endl;
}

template<class Type>
Type Dullist<Type>::Get(int i){
	int count = 1;
	DulNode<Type>* p = first->next;
	while (p != first&&count < i){
		count++;
		p = p->next;
	}
	if (p == first)throw"位置";
	else{
		return p->data;
	}
}

template<class Type>
int Dullist<Type>::Locate(Type x){
	int count = 1;
	DulNode<Type>* p = first->next;
	while (p != first){
		if (p->data == x)return count;
		p = p->next;
		count++;
	}
	return 0;
}

template<class Type>
void Dullist<Type>::Insert(int i, Type x){
	int count = 0;
	DulNode<Type>* p = first;
	while (count < i - 1){
		p = p->next;
		count++;
	}
	DulNode<Type>* s = new DulNode<Type>;
	s->data = x;
	s->prior = p;
	s->next = p->next;
	p->next->prior = s;
	p->next = s;
}

template<class Type>
Type Dullist<Type>::Delete(int i){
	DulNode<Type>* p = first;
	int count = 0;
	while (count < i ){
		p = p->next;
		count++;
	}
	if (p == first)throw"位置";
	else{
		p->prior->next = p->next;
		p->next->prior = p->prior;
		delete p;
	}
}

template<class Type>
bool Dullist<Type>::isEqual(){
	DulNode<Type>* p = first->next;
	DulNode<Type>* q = first->prior;
	while (p != q&&p->prior != q){
		if (p->data == q->data){
			p = p->next;
			q = q->prior;
		}
		else return false;
	}
	return true;
}

main.cpp

#include "dullist.cpp"
#include "dullist.h"
int main(){
	int a[7] = { 1, 2, 3, 4,3,2,1 };
	Dullist<int> dl(a, 7);
	dl.Print();
	cout << "dl的长度是:" << dl.getLength() << endl;
	cout << "第6个结点是:" << dl.Get(6) << endl;
	cout << "4是第" << dl.Locate(4) << "个结点" << endl;
	dl.Insert(4, 10);
	cout << "在第四个位置上插入10:";
	dl.Print();
	dl.Delete(1);
	cout << "删除第1个结点:";
	dl.Print();
	cout << "dl" << (dl.isEqual() == true ? "是" : "不是") << "对称的" << endl;
	return 0;
}

测试结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值