查找未知链表长度的中间结点

查找未知链表长度的中间结点

众所周知,链表是不知道长度的,如果想知道长度只能通过遍历一遍链表才可得知,因此对于查找未知链表长度的中间结点可以有很多方法。
最简单的方法就是通过遍历一边链表得到长度L,再通过遍历L/2的链表得到中间结点,此时时间复杂度就是o(L+L/2).
而另一种更简便方法则为通过建立两个指针,第一个指针为第二个指针速度的两倍,那么当第一个指针到达链表末尾的时候,就可以得知此时第二个指针在中间结点。
代码如下:
注:initLink为初始化链表,即添加根节点,添加结点的方法为尾插法,在其他文章中有写到,在这里直接使用。

public class ForMidNode {
    public void forMidNode(Linkedlist linkedlist){
        //first 的速度是follow的两倍,当first到末尾时,follow位于中间结点
        Node first =new Node();
        Node follow=new Node();
//先将两个指针放于同一结点,默认链表不为空,为空加个判断即可
        first=linkedlist.root.next;
        follow=linkedlist.root.next;
        int i=1;
        while (first.next!=null){
            first=first.next;
            if(i%2==0){
                follow=follow.next;
            }
            i++;
            System.out.println("此时的first指向的数组是"+first.getData());
            System.out.println("此时的follow指向的数组是"+follow.getData());
        }
        System.out.println("最后的first指向的数组是"+first.getData());
        System.out.println("中间结点的数值是:"+follow.getData());
    }
    public static void main(String [] args){
        ForMidNode forMidNode=new ForMidNode();
        Linkedlist linkedlist=new Linkedlist();
        linkedlist.initLink();
        linkedlist.insertForTail(1);
        linkedlist.insertForTail(2);
        linkedlist.insertForTail(3);
        linkedlist.insertForTail(4);
        linkedlist.insertForTail(5);
        linkedlist.insertForTail(6);
        linkedlist.insertForTail(7);
        linkedlist.insertForTail(8);
        linkedlist.insertForTail(9);
       forMidNode.forMidNode(linkedlist);
    }
}

运行结果:
在这里插入图片描述

而下边的方法是刚刚方法的改进,在上边方法中可以看到,虽然说我们是在同时时间进行两个指针的遍历,但是我们采用的方法是,第一个指针一直移动,第二个指针等一段时间停止移动,这样的等待就会造成时间浪费,而且第一个指针也会对每一个结点进行遍历,因此我们对此进行改进,让第一个的指针的速度真正成为第二个指针速度的两倍,即让第一个指针永远指向next的next(如果next的next不为空的情况下),代码如下:

public void forMidNode1(Linkedlist linkedlist){
        //first 的速度是follow的两倍,当first到末尾时,follow位于中间结点
        Node first =new Node();
        Node follow=new Node();

        first=linkedlist.root.next;
        follow=linkedlist.root.next;

        while (first.next!=null){

            if(first.next.next!=null){
                first=first.next.next;
                follow=follow.next;
            }
             else first=first.next;
            System.out.println("此时的first指向的数组是"+first.getData());
            System.out.println("此时的follow指向的数组是"+follow.getData());
        }
        System.out.println("最后的first指向的数组是"+first.getData());
        System.out.println("中间结点的数值是:"+follow.getData());
    }

运行结果:
从运行结果来看,也可以发现少运行了很多环节。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值