雙向鏈表的遍歷要比單向鏈表方便很多,所以逆置方法要比單鏈表豐富很多,因爲可以從後向前遍歷,所以可以像逆置數組一樣進行操作,也可以根據單鏈表的特性進行逆置,也可以用雙鏈表獨有的特性進行逆置。具體方法如下:
鏈表的類定義如下:
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