c++实现双向链表的常用功能

//结构体的定义
struct Node
{
	Node(const DataType& d)
		:_next(NULL)
		,_prev(NULL)
		,_data(d)
	{}
public:
	DataType _data;
	Node* _prev;
	Node* _next;
};
//双向链表类的定义
class DouList
{
	friend ostream& operator<<(ostream& os, DouList& l);
public:
	DouList()//构造函数
		:_head(NULL)
		,_tail(NULL)
	{}

	DouList(const DouList& l)//拷贝构造
	{
		if (l._head == NULL)
		{
			return;
		}
		Node *cur = l._head;
		Node *newNode = new Node(cur->_data);
		_head = newNode;
		_tail = _head;
		cur = cur->_next;
		while (cur)
		{
			newNode = new Node(cur->_data);
			_tail->_next = newNode;
			newNode->_prev = _tail;
			_tail = newNode;
			cur = cur->_next;
		}
	}

	DouList& operator=(DouList l)//=运算符的重载
	{
		swap(_head,l._head);
		swap(_tail, l._tail);
		return *this;
	}

	~DouList()//析构函数
	{
		Node* cur = _head;
		while (cur)
		{
			Node* del = cur;
			cur = cur->_next;
			delete del;
		}
		_head = NULL;
		_tail = NULL;
	}

public:
	void PushBack(const DataType& d);//后插
	void PopBack();//后出
	void PushFront(const DataType& d);//前插
	void PopFront();//前出
	Node* Find(const DataType& d);//查找
	void Insert(Node* pos, const DataType& d);//在指定位置插入
	void BubbSort();//冒泡排序
	void Reverse();//逆序
	void Remove(const DataType& d);//删除指定的元素
	void RemoveAll(const DataType& d);//删除所有指定的元素
	void Erase(Node* pos);//删除指定的节点
private:
	Node* _head;//头指针
	Node* _tail;//尾指针
};

ostream& operator<<(ostream& os, DouList& l)//输出运算符的重载
{
	Node* cur = l._head;
	while (cur)
	{
		os << cur->_data << "<=>";
		cur = cur->_next;
	}
	cout << "over";
	return os;
}

void DouList::PushBack(const DataType& d)
{
	Node* newNode = new Node(d);
	if (_head == NULL)
	{
		_head = newNode;
		_tail = _head;
	}
	else
	{
		_tail->_next = newNode;
		newNode->_prev = _tail;
		_tail = newNode;
	}
}

void DouList::PopBack()
{
	if (_head == NULL)
	{
		return;
	}
	if (_head == _tail)
	{
		delete _head;
		_head = NULL;
		_tail = NULL;
		return;
	}
	Node* del = _tail;
	_tail = _tail->_prev;
	_tail->_next = NULL;
	delete del;
}

void DouList::PushFront(const DataType& d)
{
	Node* newNode = new Node(d);
	if (_head == NULL)
	{
		_head = newNode;
		_tail = _head;
	}
	else
	{
		newNode->_next = _head;
		_head->_prev = newNode;
		_head = newNode;
	}

}

void DouList::PopFront()
{
	if (_head == NULL)
	{
		return;
	}
	if (_head == _tail)
	{
		delete _head;
		_head = NULL;
		_tail = NULL;
		return;
	}
	Node* del = _head;
	_head = _head->_next;
	_head->_prev = NULL;
	delete del;
}

Node* DouList::Find(const DataType& d)
{
	Node* cur = _head;
	while (cur)
	{
		if (cur->_data == d)
		{
			return cur;
		}
		cur = cur->_next;
	}
	return NULL;
}

void DouList::Insert(Node* pos, const DataType& d)
{
	if (pos == NULL)
	{
		return;
	}
	Node* newNode = new Node(d);
	if (pos != _tail)//非尾节点插入
	{
		newNode->_next = pos->_next;
		newNode->_prev = pos;
		pos->_next = newNode;
	}
	else//尾节点插入
	{
		_tail->_next = newNode;
		newNode->_prev = _tail;
		_tail = newNode;
	}
}

void DouList::BubbSort()
{
	Node* cur = _head;
	Node* end = NULL;
	bool flag = true;
	while (cur->_next != end && flag)
	{
		flag = false;
		while (cur->_next != end && cur)
		{
			if (cur->_data > cur->_next->_data)
			{
				flag = true;
				swap(cur->_data, cur->_next->_data);
			}
			cur = cur->_next;
		}
		end = cur;
		cur = _head;
	}
}

void DouList::Reverse()
{
	Node* cur = _head;
	Node* newHead = NULL;
	Node* tmp = NULL;
	while (cur)
	{
		tmp = cur->_next;
		cur->_next = newHead;
		if (newHead)
		{
			newHead->_prev = cur;
		}
		newHead = cur;
		newHead->_prev = NULL;
		cur = tmp;
	}
	swap(_head, _tail);
}

void DouList::Remove(const DataType& d)
{
	if (_head == NULL)//无节点
	{
		return;
	}
	Node* cur = _head;
	while (cur)
	{
		if (cur->_data == d)
		{
			if (cur == _head)//第一个相等
			{
				PopFront();
				return;
			}
			else if (cur == _tail&& _head != _tail)//最后一个节点相等
			{
				PopBack();
				return;
			}
			else//其他节点
			{
				cur->_prev->_next = cur->_next;
				cur->_next->_prev = cur->_prev;
				delete cur;
				return;
			}
		}
		cur = cur->_next;
	}
}

void DouList::RemoveAll(const DataType& d)
{
	Node* cur = _head;
	bool flag = true;
	while (cur)
	{
		flag = true;
		if (cur->_data == d)
		{
			flag = false;
			cur = cur->_next;
			Remove(d);
		}
		if (flag)
		{
			cur = cur->_next;
		}
	}
}

void DouList::Erase(Node* pos)
{
	if (pos == NULL)//
	{
		return;
	}
	if (pos == _head)//删除第一个节点
	{
		PopFront();
		return;
	}
	if (pos == _tail)//删除最后一个节点
	{
		PopBack();
		return;
	}
	//非尾节点的删除
	pos->_next->_prev = pos->_prev;
	pos->_prev->_next = pos->_next;
}
时间: 2024-12-28 16:46:51

c++实现双向链表的常用功能的相关文章

js常用功能代码

js常用功能代码(持续更新): 1,--折叠与展开 <input id="btnDisplay" type="button" class="baocun2" value="添加" onclick="changeDisplay()" /> <script type="text/javascript"> function changeDisplay() { var h

SVN的安装与常用功能使用以及解决安装配置过程中的一些错误

SVN简介: SVN是Subversion的简称,是一个开放源代码的版本控制系统,将工程代码集中在服务器上进行一个统一的集中式管理,从而能够方便地控制代码版本,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Subversion.说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的,而且通过使用SVN开发人员之间[学Java,到凯哥学堂kaige123.com]能够很方便的更新.提交工程代码,并且如果工程的版本有冲突还

WebStorm常用功能的使用技巧分享

WebStorm 是 JetBrain 公司开发的一款 JavaScript IDE,使用非常方便,可以使编写代码过程更加流畅. 本文在这里分享一些常用功能的使用技巧,希望能帮助大家更好的使用这款强大的 JavaScript 开发工具. 代码编辑 代码跳转: Ctrl + 左键 或者 Ctrl + B,可以跳转到函数或者变量的声明位置 调用位置: Alt + F7,查找调用者 自动补全: 最好是修改一下响应时间,Settings->Editors->General->Code Compl

项目中常用功能,如:流媒体、健康数据(步数等)等-b

整理iOS开发中使用的各种流媒体和常用的高级功能.由于时间关系,目前只写了一部分功能,全部都采用的是系统方法,没用第三方,截图如下: screen1.png screen2.png 个人比较懒,不爱多写文字,直接上代码,哈哈. 视频 系统用AVFoundation与MediaPlayer框架实现播放视频的方案.其中AVFoundation扩展性好,都需自定义功能,而MediaPlayer集成简单,但是样式不可扩展. 1.AVFoundation使用AVPlayer播放视频,它属于view的lay

【C++/STL】list的实现(没有采用迭代器和空间配置器所实现的双向链表的基本功能)

<span style="font-size:18px;">#include <iostream> using namespace std; //没有采用迭代器和空间配置器所实现的双向链表的基本功能 template<class _Ty> //定义模板类 class list //list类 { public: typedef size_t size_type; //类型重定义 protected: struct _Node; //结构体_Node

html(三) -- 常用功能标签

媒体标签 <embed></embed> 属性:        hidden : 设置隐藏插件是否隐藏.        src :用于指定音乐的路径 超链接标签 <a></a> 属性: href  : 用于指定链接的资源.常用协议:file:. mailTo:. http:      target: 设置打开新资源的目标.属性对应的值:_Blank 在独立的窗口上打开新资源   _self 在当前窗口打开新资源. a标签的原理:    1. a标签的href

IOS开发-OC学习-常用功能代码片段整理

IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是在做与URL有关的功能时,需要在Info.plist中添加一段代码进而实现让网址完成从Http到Https的转换,以及其他的一些功能. 在从一个新手到逐渐学会各种功能.代码.控件.方法如何使用的过程中,也在逐渐积累一些知识,但是一次总不会把这些东西都深刻记住并完全理解.所以在这儿记录下这些东西,用来

keepalived高可用的常用功能介绍

Keepalived的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器.本篇文章会介绍keepalived的安装,配置,还有keepalived的一些脚本,keepalived+nginx高可用实现和keepalived双机互为主从的实现. keep

WebPack常用功能介绍

概述 Webpack是一款用户打包前端模块的工具.主要是用来打包在浏览器端使用的javascript的.同时也能转换.捆绑.打包其他的静态资源,包括css.image.font file.template等.个人认为它的优点就是易用,而且常用功能基本都有,另外可以通过自己开发loader和plugin来满足自己的需求.这里就尽量详细的来介绍下一些基本功能的使用. 上一篇已经介绍如何安装了,这里就不再重复了. 运行webpack webpack需要编写一个config文件,然后根据这个文件来执行需