k_eckel:http://www.mscenter.edu.cn/blog/k_eckel & http://k-eckel.cnblogs.com
以前在学习数据结构的时候曾经被这样一个问题郁闷过:给定一个单链表,编程实现其逆转。如今再拾起来,已然渐渐觉得不是特别复杂。单链表的逆转过程的关键是3个指针:一个记录当前逆转节点的前一个节点,一个记录当前逆转节点的下一个节点,另外一个则记录当前的逆转节点。为什么要3个指针呢?其原因就在于当修改了当前逆转节点的next域后(逆转),链表就暂时断了(即无法再定位下一个节点),因此需要一个指针记录其下一个节点位置(要能够依次遍历)。记录前一个节点位置则很明显:因为要将当前逆转节点的next域指向其上一个节点(这样才叫逆转)。具体实现源码如下:
#include <iostream> #include <ctime> //定义链表节点结构 struct Node { public: Node():_val(0),_next(NULL) { } Node(int val):_val(val),_next(NULL) { } Node(int val,Node* next):_val(val),_next(next) { } ~Node() { if (_next) delete _next; } public: int _val; Node* _next; }; typedef Node* LinkNode; //创建一个链表 Node* CreateLink(int len,int MAX_BOUND = 100) { srand((unsigned int)time(NULL)); LinkNode head = new Node(-1); LinkNode tmp = head; for (int i = 0; i < len; ++i) { tmp = tmp->_next = new Node(rand() % MAX_BOUND); } tmp->_next = NULL; return head; } //链表逆转 Node* LinkListReserve(LinkNode head) { LinkNode p = NULL; //记录逆转节点的前一个节点; LinkNode r = head; //记录当前节点; LinkNode q = NULL; //记录逆转节点的下一个节点; while (r != NULL) { q = r->_next; //保存下一个节点 r->_next = p; //逆转 p = r; //下一次遍历 r = q; } return p; } //打印链表数据 void Print(LinkNode head) { using namespace std; cout<<".......begin......"<<endl; while (head != NULL) { cout<<head->_val<<" "; head = head->_next; } cout<<endl<<".......end........"<<endl; } |
int main(int argc,char* argv[]) { Node* head = CreateLink(4); Print(head); Print(LinkListReserve(head)); return 0; } |