双向链表的遍历要比单向链表方便很多,所以逆置方法要比单链表丰富很多,因为可以从后向前遍历,所以可以像逆置数组一样进行操作,也可以根据单链表的特性进行逆置,也可以用双链表独有的特性进行逆置。具体方法如下:
链表的类定义如下:
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;
}
如有不足或错误,希望批评指正。
转载于:https://blog.51cto.com/10743407/1747812