单向链表--------反转链表--------递归和迭代

题目

迭代解法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* curr = head;
        ListNode* pro = NULL;
        while(curr){
            ListNode* next = curr->next;
            curr->next = pro;
            pro = curr;
            curr = next;
        }
        return pro;
    }
};

这里我们运用迭代的方法,定义一个curr指针暂存头节点,然后定义curr的前驱节点和后继节点,利用这三个节点,实现链表的逆序,就是让每个节点的指针域反转。

其一定义三个指针,让curr的前驱节点指向NULL;

其二利用while循环,首先利用next暂存curr的后继节点,然后让curr的后继节点置为pro,紧接着让pro指向curr对应地址,再让curr指向next对应地址,循环往复,节点就逆转了。

这里注意,当节点指针域改变以后,就不能利用Node->next来偏移指针了,这也是定义后继节点的目的。

递归解法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL||head->next==NULL){
            return head;
        }
        ListNode* newhead = reverseList(head->next);
        head->next->next = head;
        head->next = NULL;
        return newhead;
    }
};

经过两天的鏖战,终于是拿下了这个递归的解法,我现在对这个题目是完全理解啦,递归真是个美妙的解法,神奇且魔幻,接下来我将以另外的形式呈现我的想法:

//1 ->2 ->3 ->4 ->5
//h1  h2  h3  h4  h5
ListNode* hanshu1(ListNode* h1){
    if(head==NULL||head->next==NULL){
        return h1;
    }
    ListNode* h2 = h1->next;
    ListNode* newh = hanshu2(h2);
    h1->next->next = h1;
    h1->next = NULL;
    return newh;
}
ListNode* hanshu2(ListNode* h2){
    if(head==NULL||head->next==NULL){
        return h2;
    }  
    ListNode* h3 = h2->next;
    ListNode* newh = hanshu3(h3);
    h2->next->next = h2
    h2->next = NULL; 
    return newh;
}
ListNode* hanshu3(ListNode* h3){
    if(head==NULL||head->next==NULL){
        return h3;
    }  
    ListNode* h4 = h3->next;
    ListNode* newh = hanshu4(h4);
    h3->next->next = h3
    h3->next = NULL; 
    return newh;
}
ListNode* hanshu4(ListNode* h4){
    if(head==NULL||head->next==NULL){
        return h4;
    }  
    ListNode* h5 = h4->next;
    ListNode* newh = hanshu5(h5);
    h4->next->next = h4
    h4->next = NULL; 
    return newh;
}
ListNode* hanshu5(ListNode* h5){
    if(head==NULL||head->next==NULL){
        return h5;
    }  
    ListNode* h6 = h5->next;
    ListNode* newh = hanshu6(h6);
    h5->next->next = h5
    h5->next = NULL; 
    return newh;
}
ListNode* hanshu6(ListNode* h6){
    if(head==NULL||head->next==NULL){
        return h6;
    }  
    ListNode* h7 = h6->next;
    ListNode* newh = hanshu7(h7);
    h6->next->next = h6
    h6->next = NULL; 
    return newh;
}
     
             

其实呢,就可以看作是一个函数接一个函数的嵌套,函数不断被调用,直到if语句触发,返回目标头节点,然后就一层一层往外返回,在每一次返回之后,改变指针域朝向,实现链表反转。

上面的演示代码中,hanshu1到hanshu6其实代表的都是同一个函数,这个函数以不同的参数传入,被调用了6次,然后一层一层地返回,实现整个过程。

我举一个例子,一群矿工一个接一个地排成一排,进入一个洞穴,顺序是第一个先进去,然后第二个人,紧接着第三个人。。。当第一个人走到洞穴尽头的时候,就会转身告诉第二个人,紧接着第二个人转身告诉第三个人,最终告诉最后一个人,他们才能出去。

反思

1.考察知识点:单向链表,前驱指针和后继指针

2.踩的坑:对于指针的利用还不够规范,思路不够正式;

3.待会儿补充递归法。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值