Java单链表的反转

前段时间有同事面试,给面试的人都提一个算法问题那就是单链表的反转,好多小伙伴都不会,或者表示一听算法就懵逼了,自己写了一个。就是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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值