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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}


以上是关于c++实现双向链表的常用功能的主要内容,如果未能解决你的问题,请参考以下文章

双向链表的基础操作(C++实现)

双向链表的增删改查C++完整实现

数据结构双向链表的实现

c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)

C++基于双向链表的List

常用数据结构:单向链表和双向链表的实现