【总结】逆置双向链表的三种方法

    双向链表的遍历要比单向链表方便很多,所以逆置方法要比单链表丰富很多,因为可以从后向前遍历,所以可以像逆置数组一样进行操作,也可以根据单链表的特性进行逆置,也可以用双链表独有的特性进行逆置。具体方法如下:

    链表的类定义如下:

typedef int DataType;
class DSNode
{
public:
	friend class DNSList;
	DSNode(DataType x=0)
		:_data(x),
		_next(NULL),
		_prev(NULL)
	{

	}
private:

	DSNode*_prev;
	DSNode*_next;
	DataType _data;

};
class DNSList
{
public:
	DNSList()
		:_head(NULL),
		_tail(NULL)
	{

	}
	~DNSList()
	{
		_Clear();
	}
	DNSList(const DNSList &l)
	{
		DSNode *cur = l._head;
		while (cur)
		{
			PushBack(cur->_data);
		}
	}
	DNSList operator = (DNSList l)
	{
		_Clear();
		DSNode *cur = l._head;
		while (cur)
		{
			PushBack(cur->_data);
		}
	}
public:
	// 头插/头删/尾插/尾删
	void PushBack(const DataType& x);
	void PopBack();
	void PushFront(const DataType& x);
	void PopFront();

	// 插入/查找/删除
	void Insert(DSNode* pos, const DataType& x);
	DSNode* Find(const DataType& x);
	void Erase(const DataType& x);
	//void Reverse();//同一空间复杂度不需要返回值
	DNSList* Reverse();//不同空间复杂度通过链表指针返回

	// 打印
	void Print();


private:
	void _Clear()
	{
		while (_head)
		{
			DSNode*cur = _head;
			_head = _head->_next;
			delete cur;
		}
	}
	DSNode *_head;
	DSNode *_tail;
};

    在单一空间复杂度下:

    1.通过头尾指针向中间遍历,交换所存储的内容。

void DNSList::Reverse()
{
	DSNode *begin = _head;
	DSNode *end = _tail;
	while (!(begin==end||begin->_prev==end))
	{
		DataType tmp = begin->_data;
		begin->_data = end->_data;
		end->_data = tmp;
		end = end->_prev;
		begin = begin->_next;
	}
}

    2.单纯通过头指针向后遍历,交换每个节点的前驱与后继。

void DNSList::Reverse()
{
	std::swap(_head, _tail);
	DSNode*cur = _head;
	while (cur)
	{
		std::swap(cur->_next, cur->_prev);
		cur = cur->_next;
	}
}

    在多重空间复杂度下:

    创建新的双向链表指针,将目标链表从前向后遍历/从后向前遍历,把每个节点的元素进行头插/尾插。

DNSList* DNSList::Reverse()
{
	DNSList*NewList = new DNSList;
	DSNode *cur = _head;
	while (cur)
	{
		NewList->PushFront(cur->_data);
		cur = cur->_next;
	}
	return NewList;
}

    如有不足或错误,希望批评指正。

本文出自 “pawnsir的IT之路” 博客,请务必保留此出处http://10743407.blog.51cto.com/10733407/1747812

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值