zoukankan      html  css  js  c++  java
  • 剑指offer—单链表反转的三种实现方法

    单链表的反转可以用递归、非递归和栈的方法实现

    链表节点定义:

    struct ListNode{
        int val;
        Node* next;
        ListNode(int x):val(x),next(nullptr){}
    }
    

    1、栈

    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next)
           	return head;
        stack<ListNode*>stk;
        //将链表的结点全部压进栈
        while(head){
            stk.push(head);
            head = head->next;
        }
        ListNode*cur,*nxt;
        cur = nxt = stk.top();
        stk.pop();
        while(!stk.empty()){
            nxt ->next = stk.top();
            nxt = nxt ->next;
            stk.pop();
        }
        //最后一个结点的next记得要指向nullptr
        nxt ->next =nullptr;
        return cur;
    }
    

    2、递归

    利用递归,直到链表的最后一个节点,用一个指针指向该节点,作为反转后的链表的头节点
    在递归返回的过程中,让该节点的下一个节点指向该节点((head->next->next=head))
    并让该节点指向(NULL)。这样就从链表尾部一步步实现了反转

    Ps:图片来自网络侵权删

    ListNode* reverseList(ListNode* head) {
        if(head==NULL || head->next==NULL)  
            return head;
        ListNode* ptr=reverseList(head->next);
        head->next->next=head;
        head->next=NULL;
        
    	return ptr;
    }
    

    3、双指针

    利用两个结点指针和一个中间结点指针 (temp(用来记录当前结点的下一个节点的位置)),分别指向当前结点和前一个结点,每次循环让当前结点的指针域指向前一个结点即可

    ListNode* reverseList(ListNode* head) {
        ListNode* cur=head;
        ListNode* pre=nullptr;
        while(cur)
        {
            ListNode* tmp=cur->next;
            cur->next=pre;
            pre=cur;
            cur=tmp;
        }
        return pre;
    }
    
  • 相关阅读:
    poj 3304 直线与线段相交
    poj 2318 叉积+二分
    AC自动机
    MySQL报错:Packets larger than max_allowed_packet are not allowed 的解决方案
    SCOPE_IDENTITY的作用
    Truncate table、Delete与Drop table的区别
    .Net Attribute特性
    vs2010 调试快捷键
    TFS和VSS的简单对比
    做网站用UTF-8还是GB2312 & 各国语言对应字符集
  • 原文地址:https://www.cnblogs.com/RioTian/p/12614568.html
Copyright © 2011-2022 走看看