双向链表的遍历要比单向链表方便很多,所以逆置方法要比单链表丰富很多,因为可以从后向前遍历,所以可以像逆置数组一样进行操作,也可以根据单链表的特性进行逆置,也可以用双链表独有的特性进行逆置。具体方法如下:
链表的类定义如下:
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
原文地址:http://10743407.blog.51cto.com/10733407/1747812