单链表的反转

来源:互联网 发布:手机淘宝商家登陆 编辑:程序博客网 时间:2024/05/24 01:57

链表是数据结构中比较重要的一段内容,面试中也很多关于链表的问题。今天学习了链表的反转,总结一下,大致有5个方法。

结构体声明如下

/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/

1.将旧链表内容存进数组,再倒序的方式存入链表

比较浪费空间,需要多次遍历,但是比较容易。这里不再赘述。


2.从p->next开始遍历,不断把节点插到head的后面

      head

         ↓

比如 1——2——3——4——5

         1——3——2——4——5

         1——4——3——2——5

         1——5——4——3——2

最后通过首尾相连,再断链的方法就完成了。 如果你的链表是有空链表头的,那么则可以省去最后的连接步骤。

class Solution {public:    ListNode* ReverseList(ListNode* pHead) {        ListNode* p = pHead->next;        ListNode* q;        while(p->next != NULL){ //把P的后面一个节点插入头部后面            q = p->next;            p->next = q->next;            q->next = pHead->next;            pHead->next = q;        }        p->next = pHead;        //成环        pHead = p->next->next;  //头部向后移一个        p->next->next = NULL;   //断链                return pHead;    }};


3.创建一个新表,遍历旧表,把节点依次插入新表的头部

class Solution {public:    ListNode* ReverseList(ListNode* pHead) {        ListNode* oldList = pHead;        ListNode* newList = NULL;        ListNode* tmp;        while(oldList != NULL){            tmp = oldList;         // 得到要插入的节点            oldList = tmp->next;   // oldList 向后移            tmp->next = newList;   // 把新表插入 tmp 后面            newList = tmp;         // 新表此时 head 为tmp        }        return newList;    }};

4.用三个指针,遍历一次链表,完成每个节点都指向前面节点的工作

即 从                  A > B > C > D > E > NULL

     到   NULL < A < B < C < D < E      的过程

class Solution {public:    ListNode* ReverseList(ListNode* pHead) {        if(pHead == NULL)             return NULL;        ListNode* pre = NULL;        ListNode* next = NULL;        ListNode* head = pHead;        while(head != NULL){            next = head->next;            head->next = pre;            pre = head;            head = next;        }        return pre;    }};


5.递归方法。

递归的方法相对来说就很巧妙了,用递归一直移动到链表的最后,返回一个newHead,这是我们的新头节点

从递归结束的时候开始分析,过程大概是这样的:节点从最后(newHead)遍历到pHead,除了newHead,其他任何节点都作为后一个节点的后续节点,并指向NULL

class Solution {public:    ListNode* ReverseList(ListNode* pHead) {        if(pHead == NULL) // 鲁棒性            return NULL;        if(pHead->next == NULL){ //当找到最后一个节点,返回这个节点作为newHead            return pHead;        }        ListNode* newHead = ReverseList(pHead->next);  //保存newHead        pHead->next->next = pHead;                     //作为后一个节点的后续节点        pHead->next = NULL;        return newHead;    }};

总结:

1.对链表的操作要非常仔细,有些操作调换一下上下位置,含义可能是完全不一样的。要想清楚逻辑以后再动手

2.什么问题其实都不妨尝试想一想递归操作能否实现。


留个问题:这是最基本的单链表的反转,那么其他链表呢?


原创粉丝点击