大话数据结构 —— 双向链表 C#、C++代码实现

 


双向列表


 双向链表是每个结点除后继指针外还有一个前驱指针。和单链表类同,双向链表也有带头结点结构和不带头结点结构两种,带头结点的双向链表更为常用;另外,双向链表也可以有循环和非循环两种结构,循环结构的双向链表更为常用。

 双向链表相当于两个单向循环链表,双链表节点结构如下图示:

 

双链表节点比单链表多一个前驱指针域。

如下图是带头结点的双向循环链表的图示结构。双向循环链表的next和prior各自构成自己的单向循环链表:

3bf0b73d-1b95-4445-bbf4-5d0d6ca00f37

 

在双向链表中,有如下关系:设对象引用p表示双向链表中的第i个结点,则p->next表示第i+1个结点,p->next->prior仍表示第i个结点,即p->next->prior == p;同样地,p->prior表示第i-1个结点,p->prior->next仍表示第i个结点,即p->prior->next == p。下图是双向链表上述关系的图示:

3d014245-d195-4829-88fd-a66ddde03783

双向循环链表的插入过程:

  下图中的指针p表示要插入结点的位置,s表示要插入的结点,①、②、③、④表示实现插入过程的步骤:

ff952782-ed50-4c3b-92cc-4eea4fbe63e9

s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;

循环双向链表的删除过程:

  下图中的指针p表示要插入结点的位置,①、②表示实现删除过程的步骤:

be7a99c0-7ed3-4fbd-837a-6d229710a683

p->prior->next = p->next;
p->next->prior = p->prior;

下面用C++ 代码实现双向链表:

头文件:

#include<iostream>
using namespace std;
#ifndef TT_DU_LINK_LIST
#define TT_DU_LINK_LIST
#define TT_OK 1
#define TT_ERROR 0
namespace tt

{
	class  DuLinkList
	{
	public:
		typedef  int ElemType;
		typedef void Status;
	public:
		struct DulNode
		{
			ElemType m_data;  //数据域
			DulNode *m_prior;   //指向前驱结点的指针
			DulNode *m_next;    //指向后继结点的指针
		};
	public:
		DuLinkList();
		~DuLinkList();
		ElemType insertAt(ElemType i, ElemType elem);
		ElemType removeAt(ElemType i, ElemType &elemOut);
		ElemType getAt(ElemType i, ElemType &elemOut);
		ElemType getIndexElemAt(ElemType &i, ElemType elemOut);//查找与elem相等的元素,返回第一个与elem相等元素在链表中的序号
		ElemType getLength()const;
		ElemType isEmpty()const;
		ElemType destroy();
		ElemType clear();
		Status show();
		Status traverseBack();
		ElemType priorElemAt(ElemType cur_e, ElemType &pri_e);//若cur_e是链表的数据元素,且不是第一个,则用pre_e返回它的前驱
		ElemType nextElemAt(ElemType cur_e, ElemType &Nex_e); //若cur_e是链表的数据元素,且不是最后一个,则用next_e返回它的后继,
		Status createTail(ElemType *datas, ElemType length);//创建长度为length的链表,数据通过数组指定,这里采用尾插法
	private:
		DulNode *m_heap;
	};
	inline DuLinkList::ElemType DuLinkList::isEmpty()const
	{
		return ((m_heap->m_next == m_heap) && (m_heap->m_prior == m_heap));
	}
}
#endif  //TT_DU_LINK_LIST

源文件:

#include"MyDuLinkList.h"

namespace tt
{
	DuLinkList::DuLinkList()
	{
		m_heap = new DulNode;
		if (!m_heap)
		{
			cout << "错误,内存分配失败!" << endl;
			system("pause");
			exit(0);
		}
		/*m_heap->m_next = m_heap;
		m_heap->m_prior = m_heap;*/
		m_heap->m_next = m_heap->m_prior = m_heap;
		cout << "\n********************双向的循环链表初始化成功!************************" << endl;
	}
	DuLinkList::~DuLinkList()
	{
		this->destroy();

	}

	DuLinkList::Status DuLinkList::createTail(ElemType *datas, ElemType length)//创建长度为length的链表,数据通过数组指定,这里采用尾插法
	{
		DulNode *m = m_heap;
		for (int i = 0; i < length; ++i)
		{
			DulNode *p = new DulNode;
			if (!p)
			{
				cout << "错误,无法分配内存,创建链表失败!" << endl;
				system("pause");
				exit(0);
			}
			p->m_data = datas[i]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值