链表之双链表

双链表是一种数据结构,每个节点包含前驱和后继的指针,允许双向遍历。其特点在于易于找到节点的前后节点,但插入和删除操作相对复杂,且每个节点占用更多内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.定义

双链表是由一系列节点连接起来的数据结构,通过当前节点都可以找到前一个节点和下一个节点。

2.特点

使用方法,组成和内存存储方式等和单链表一样

优点:可以找到某个节点的前驱和后继,可进可退。

缺点:增加,删除节点复杂;因为每个节点的数据结构中多一个指针,所以多占一个指针的内存空间;

3.实现

template<class T> 
struct DNode 
{
public:
	T value;
	DNode *prev;
	DNode *next;
public:
	DNode() { }
	DNode(T t, DNode *prev, DNode *next) {
		this->value = t;
		this->prev  = prev;
		this->next  = next;
	}
};
//双向链表基本操作
template<class T> 
class DoubleLink 
{
public:
	DoubleLink();
	~DoubleLink();
 
	int size();//大小
	int is_empty();//判断是否为空
 
	T get(int index);//获取节点
	T get_first();//获取首节点
	T get_last();//获取尾节点
 
	int insert(int index, T t);
	int insert_first(T t);
	int append_last(T t);
 
	int del(int index);
	int delete_first();
	int delete_last();
 
private:
	int count;
	DNode<T> *phead;
private:
	DNode<T> *get_node(int index);
};
 
template<class T>
DoubleLink<T>::DoubleLink() : count(0)
{
	// 创建“表头”。注意:表头没有存储数据!
	phead = new DNode<T>();
	phead->prev = phead->next = phead;
	// 设置链表计数为0
	//count = 0;
}
 
// 析构函数
template<class T>
DoubleLink<T>::~DoubleLink() 
{
	// 删除所有的节点
	DNode<T>* ptmp;
	DNode<T>* pnode = phead->next;
	while (pnode != phead)
	{
		ptmp = pnode;
		pnode=pnode->next;
		delete ptmp;
	}
 
	// 删除"表头"
	delete phead;
	phead = NULL;
}
 
// 返回节点数目
template<class T>
int DoubleLink<T>::size() 
{
	return count;
}
 
// 返回链表是否为空
template<class T>
int DoubleLink<T>::is_empty() 
{
	return count==0;
}
 
// 获取第index位置的节点
template<class T>
DNode<T>* DoubleLink<T>::get_node(int index) 
{
	// 判断参数有效性
	if (index<0 || index>=count)
	{
		cout << "get node failed! the index in out of bound!" << endl;
		return NULL;
	}
 
	// 正向查找
	if (index <= count/2)
	{
		int i=0;
		DNode<T>* pindex = phead->next;
		while (i++ < index) {
			pindex = pindex->next;
		}
 
		return pindex;
	}
 
	// 反向查找
	int j=0;
	int rindex = count - index -1;
	DNode<T>* prindex = phead->prev;
	while (j++ < rindex) {
		prindex = prindex->prev;
	}
 
	return prindex;
}
 
// 获取第index位置的节点的值
template<class T>
T DoubleLink<T>::get(int index) 
{
	return get_node(index)->value;
}
 
// 获取第1个节点的值
template<class T>
T DoubleLink<T>::get_first() 
{
	return get_node(0)->value;
}
 
// 获取最后一个节点的值
template<class T>
T DoubleLink<T>::get_last() 
{
	return get_node(count-1)->value;
}
 
// 将节点插入到第index位置之前
template<class T>
int DoubleLink<T>::insert(int index, T t) 
{
	if (index == 0)
		return insert_first(t);
 
	DNode<T>* pindex = get_node(index);
	DNode<T>* pnode  = new DNode<T>(t, pindex->prev, pindex);
	pindex->prev->next = pnode;
	pindex->prev = pnode;
	count++;
 
	return 0;
}
 
// 将节点插入第一个节点处。
template<class T>
int DoubleLink<T>::insert_first(T t) 
{
	DNode<T>* pnode  = new DNode<T>(t, phead, phead->next);
	phead->next->prev = pnode;
	phead->next = pnode;
	count++;
 
	return 0;
}
 
// 将节点追加到链表的末尾
template<class T>
int DoubleLink<T>::append_last(T t) 
{
	DNode<T>* pnode = new DNode<T>(t, phead->prev, phead);
	phead->prev->next = pnode;
	phead->prev = pnode;
	count++;
 
	return 0;
}
 
// 删除index位置的节点
template<class T>
int DoubleLink<T>::del(int index) 
{
	DNode<T>* pindex = get_node(index);
	pindex->next->prev = pindex->prev;
	pindex->prev->next = pindex->next;
	delete pindex;
	count--;
 
	return 0;
}
 
// 删除第一个节点
template<class T>
int DoubleLink<T>::delete_first() 
{
	return del(0);
}
 
// 删除最后一个节点
template<class T>
int DoubleLink<T>::delete_last() 
{
	return del(count-1);
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值