zoukankan      html  css  js  c++  java
  • [编程题] 借用栈实现链表反转

    链表反转

    题目描述

    定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

    image-20200625211648166

    思考分析(递归思想)

    我们可以借助栈结果,把链表存入栈中的时候,再次拿出来的时候就是逆序的了。但是要注意其中关键一步,取出的时候要消除每个节点的next域的指向(正向存入栈中的每个节点的next域的指向是没变的,比如a的next依然标记了b).最终我们返回从栈中出来的那个链表的head.

    Java代码

    import java.util.*;
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode reverseList(ListNode head) {
            //借助栈
            Deque<ListNode> stack = new LinkedList();
            ListNode newHead=null;  //返回的逆转栈
    
            //安全验证
            if(head==null) return null;
            if(head.next==null) return head;
    
            //一个个入栈
            while(head!=null){
                stack.push(head);
                head = head.next;
            }
            
            head = stack.pop();
            ListNode cur = head;
            //出栈
            while(!stack.isEmpty()){
                ListNode node = stack.pop();
                //我们虽然正向存入了栈中,但是每个节点的next的指向还没变,在这里要消除
                node.next=null;  //这一步关键(//消除正向原本的指向关系)
                cur.next = node;
                cur = node;
            }
    
            return head;
        }
    }
    

    测试:

    image-20200625211923581

    解释出栈的时候 node.next=null;代码的作用

    (1)我们把完整的案例执行输出

    package jianzhioffer;
    
    import java.util.Deque;
    import java.util.LinkedList;
    import java.util.Stack;
    
    /**
     * @author jiyongjia
     * @create 2020/6/25 - 20:25
     * @descp:
     */
    
    public class P16_reverseLinkedList {
    
        static class Node{
            String val;
            Node next;
            public Node(String val) {
                this.val = val;
            }
            @Override
            public String toString() {
                return "Node("+this.val+")";
            }
        }
    
    
    
    
        public static Node reverseLinkedList(Node head){
            Stack<Node> stack = new Stack<Node>();
            while(head!=null){
                stack.push(head);
                head = head.next;
            }
            if(!stack.isEmpty()) {
                head = stack.pop();
            }
            Node cur = head;
            System.out.println("反向操作中...");
            while(!stack.isEmpty()){
                Node node = stack.pop();
                /*//验证节点指向的测试代码
                System.out.println("node:"+node+"--->>node.Next:"+node.next);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
                
                //我们虽然是存入栈中了,但是它的next值还在,比如a的next还是正向的b;
                node.next = null;  //消除正向原本的指向关系
                cur.next = node;
                cur = node;
            }
            return head;
        }
    
        public static void display(Node head){
            System.out.print("list:");
            Node cur = head;
            while(cur!=null){
                System.out.print(cur+"->");
                cur = cur.next;
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            Node a = new Node("a");
            Node b = new Node("b");
            Node c = new Node("c");
            Node d = new Node("d");
            Node e = new Node("e");
            Node f = new Node("f");
            Node g = new Node("g");
            a.next = b;
            b.next = c;
            c.next = d;
            d.next = e;
            e.next = f;
            f.next = g;
            System.out.println("原始链表:");
            display(a);
            Node head = reverseLinkedList(a);
            System.out.println("反转之后的链表:");
            display(head);
        }
    }
    
    

    可以看到正常输出反转:

    image-20200625212125270

    我们打印出如果不同消除的话,节点的指向关系:

    修改代码如下进行验证

    while(!stack.isEmpty()){
        Node node = stack.pop();
        
        //打印节点的关系指向
        System.out.println("node:"+node+"--->>node.Next:"+node.next);
        //睡眠下才能看到效果,不然直接栈溢出
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        //我们虽然是存入栈中了,但是它的next值还在,比如a的next还是正向的b;
        //node.next = null;  //消除正向原本的指向关系
        cur.next = node;
        cur = node;
    }
    

    输出:

    (我们发现节点的指向还是正向的)

    image-20200625212340255

  • 相关阅读:
    集合的一些操作总结
    字符串的操作
    python字典的操作总结
    python中的列表知识总结
    Python利用文件操作实现用户名的存储登入操作
    如何理解:城市的“信息化→智能化→智慧化”
    程序员必备技能-怎样快速接手一个项目
    程序员的职业规划
    只要 8 个步骤,学会这个 Docker 命令终极教程!
    使用GitLab实现CI/CD
  • 原文地址:https://www.cnblogs.com/jiyongjia/p/13193008.html
Copyright © 2011-2022 走看看