Java单链表的反转

来源:互联网 发布:免费赚qq币软件 编辑:程序博客网 时间:2024/04/28 05:22

前段时间有同事面试,给面试的人都提一个算法问题那就是单链表的反转,好多小伙伴都不会,或者表示一听算法就懵逼了,自己写了一个。就是5-4-6-8-9-1-2-7,反转输出7-2-1-9-8-6-4-5,我自己写的反转有两种方式。一种是递归,一种是遍历,也是很普通的两种方式。
<一>递归的方式
先看图
这里写图片描述

先解释一下一个Node有data和next,data是数据,next是指向下一个节点,相当于C中的指针了。我们先放3个数据,图中的1-3是一次完整的操作。
先想一哈这个怎么写,既然递归,而且是链表就要传入一个头结点,就是图中的A节点,递归中要判断,下一个节点的是不是空节点来,来决定要不要再次调用自己去处理数据。
具体的递归方法怎么写,看图里面的数据是如何处理的,
注意的3点;
1.判断是不是null节点,也就是找到最后一个节点,并且返回出来作为第一个节点
2.找到最后一个节点后,将最后一个节点的next指向自己,并将自己的next复制为null,将自己设置为最后一个节点
3.递归是重复调用自己的

这个是node节点

public class Node {    private int Data;    private Node Next;    public Node(int data) {        this.Data=data;    }    public int getData() {        return Data;    }    public void setData(int data) {        Data = data;    }    public Node getNext() {        return Next;    }    public void setNext(Node next) {        Next = next;    }}

具体的递归方法看图的操作去写

public Node ergodic(Node heade){//1.判断是不是null节点,也就是找到最后一个节点,并且返回出来作为第一个节点if(heade==null||heade.next==null){return heade;//判断是最后一个节点,直接将最后一个节点往上返回}//不断调用自己找见最后一个节点Node result=ergodic(heade.getNext());//2.找到最后一个节点后,将最后一个节点的next指向自己,并将自己的next复制为null,将自己//设置为最后一个节点heade.getNext().SetNext(heade);heade.setNext(null);return result;}

具体的执行大概说一下调用ergodic
将A作为heade传入,判断是不是最后一个节点,
调用ergodic并传入A的next节点即B节点,判断B节点不是最后一个节点,调用ergodic传入B节点的next,即C节点,C节点是最后一个节点,returnC节点,result是C节点。此时的heade是B节点,将B节点的next节点的next设置为B节点,就是C节点next设置为B节点**,header现在还是B节点,将B节点的next设置为null,return了C节点,此时的result是刚才返回的C节点,heade是A节点,将A节点的next节点的next设置为A节点,即B节点的next设置为A节点,A节点的的next设置为null,返回C节点。
到此整个递归就走完了。返回的是C节点,即图中3的结果。c指向b,b指向a,反转结束了。

<一>遍历反转

就是将B节点next中的节点暂时记录,将A节点和B节点,的next重新设置,A节点的next设置为null,B节点的next设置为A节点,再进行下一轮的互换,C节点和B节点的next互换,C节点的Next指向B节点,

具体代码

public static Node ergodic(Node head) {        if (head == null) {            return head;        }        Node pre=head;//第一个节点        Node cur=head.getNext();//第二个节点        Node tmp;        while (cur!=null) {        tmp=cur.getNext();//第三个节点        cur.setNext(pre);//将第二个节点的指针指向第一个节点        //互换位置        pre=cur;//第二个节点成为前一个节点        cur=tmp;//第二个节点的下一个节点为第三个节点        }        head.setNext(null);        return pre;    }

整体的代码:

import com.sun.xml.internal.bind.util.Which;public class Listflip {    public static void main(String[] args) {        Node heaedNode = new Node(0);        Node heaedNode1 = new Node(1);        Node heaedNode2 = new Node(2);        Node heaedNode3 = new Node(3);        Node heaedNode4 = new Node(4);        heaedNode.setNext(heaedNode1);        heaedNode1.setNext(heaedNode2);        heaedNode2.setNext(heaedNode3);        heaedNode3.setNext(heaedNode4);        // 递归反转前        Node node = heaedNode;        while (node != null) {            System.out.println(node.getData() + "");            node = node.getNext();        }        // 递归反转后        node = ergodic(heaedNode);        while (node != null) {            System.out.println(node.getData() + "");            node = node.getNext();        }    }    // 递归反转    public static Node reversel(Node head) {        if (head == null || head.getNext() == null) {            return head;        }        Node renode = reversel(head.getNext());        head.getNext().setNext(head);        head.setNext(null);        return renode;    }    // 遍历反转    public static Node ergodic(Node head) {        if (head == null) {            return head;        }        Node pre=head;//第一个节点        Node cur=head.getNext();//第二个节点        Node tmp;        while (cur!=null) {        tmp=cur.getNext();//第三个节点        cur.setNext(pre);//将第二个节点的指针指向第一个节点        //互换位置        pre=cur;//第二个节点成为前一个节点        cur=tmp;//第二个节点的下一个节点为第三个节点        }        head.setNext(null);        return pre;    }}