单链表反转

关于链表反转是招聘笔试中经常考的题,而且经常是让直接写在纸上,感觉在纸上写程序比使用IDE写难好多,主要还是自己不太熟练,所以整理了一下链表的反转的方法。
关于链表反转个人想到了三种方法,使用java实现,后续看到新方法会补充……

链表反转

  1. 新链表从最后一个节点向前新建,依次拷贝原链表的数据。
  2. 先将链表中的数据拷贝到一个数组中,从数组最后一个元素依次向前新建链表,这个链表新建的方式是从前向后新建
  3. 直接使用三个变量来反转原链表

依次来看一下代码
链表结构

class Linked{
    int node;
    Linked next;
}

1、新链表从最后一个节点向前新建,依次拷贝原链表的数据。

    /**
     * 方式一
     * 思路:新建一个新的链表,新链表从最后一个节点向前新建
     * @param head
     * @return
     */
    public static Linked reverseLinked1(Linked head){
        Linked l = null;
        Linked linked = head.next;
        /**
         * 新链表从后向前构建
         */
        while(linked!=null){
            if(l == null){
                // 构建新链表末尾节点
                l= new Linked();
                l.node = linked.node;
            }else{
                // 构建当前节点l前一节点temp
                Linked temp = new Linked();
                temp.next = l;
                temp.node = linked.node;
                // 更新当前节点为前一节点
                l = temp;
            }
            // 迭代遍历原始链表
            linked = linked.next;
        }
        // 新链表的链表头
        Linked h = new Linked();
        // 链表头指向第一个节点
        h.next = l;
        return h;
    }

2、借助数组反转

    /**
     * 方式二
     * 思路:首先将链表内容拷贝到数组中,然后以数组反序新建一个链表,新链表从第一个节点向后新建
     * @param head
     * @return
     */
    public static Linked reverseLinked2(Linked head){
        // 返回的链表头
        Linked new_h = new Linked();
        // 获取输入链表的第一个节点
        Linked linked = head.next;
        // 新链表拷贝到的数组(这里提前定义数组大小如果链表节点数超过这个100就会出错)
        int[] a = new int[100];
        // 记录链表节点个数
        int k=0;
        // 拷贝链表数据到数组
        while(linked!=null){
            a[k] = linked.node;
            k++;
            linked = linked.next;
        }

        /*
         * 从头开始向后建链表
         */
        Linked l = null;
        for(int i=k-1;i>=0;i--){
            if(l==null){
                // 构建第一个节点
                l=new Linked();
                // 拷贝数据
                l.node = a[i];
                // 让新链表头指向第一个节点
                new_h.next=l;
            }else{
                // 构建下一个节点
                Linked temp = new Linked();
                // 拷贝数据
                temp.node = a[i];
                // 关联两个节点,让当前节点指向下一节点
                l.next = temp;
                // 更新当前节点
                l=temp;
            }
        }
        return new_h;
    }

3、使用三个辅助变量反转

    /**
     * 方式三
     * 使用三个变量,分别是前一节点、当前节点、后一节点来反转链表
     * @param head
     * @return
     */
    public static Linked reverseLinked3(Linked head){
        Linked current_linked = head.next;
        Linked previous_linked = null;
        while(current_linked!=null){
            // 存储当前点的下一节点
            Linked next_linked = current_linked.next;
            // 将当前点下一节点更新为前一节点(这一步实现反转)
            current_linked.next = previous_linked;
            // 前一节点更新为当前点
            previous_linked = current_linked;
            // 当前点更新为下一点
            current_linked = next_linked;
        }
        // 将链表头指向反转后的链表第一个节点
        head.next = previous_linked;
        return head;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值