Java链表练习题

题目

1.逆序输出链表

1->2->3->4->5

print() 5 4 3 2 1

2.逆置链表

1->2->3->4->5

reverse() 5->4->3->2->1

3.查找单链表中倒数第K个元素

4.合并两个有序的单链表,保证合并后的依然有序

5.不允许遍历链表, 在 pos之前插入

6.找两条相交链表的相交节点

7.判断链表是否有环,有环输出环的入口节点,无环返回null

题目分析与实现

1.使用递归的方法实现。

public static <T extends Comparable<T>> void reversePrint(MySingleLinkedList<T>.Node<T> tmp){
        //给出终止条件
        if(tmp == null){
            //满足终止条件时的解决办法
            return;
        }
        //相同的逻辑
        reversePrint(tmp.next);
        System.out.println(tmp);
    }

2.设置三个指针分别指向前驱,结点,和后继。

 //逆置链表
    public static <T extends Comparable<T>> MySingleLinkedList<T>.Node<T> reverse(MySingleLinkedList<T>.Node<T> head){
        MySingleLinkedList<T>.Node<T> current = head;
        MySingleLinkedList<T>.Node<T> prev = null;
        MySingleLinkedList<T>.Node<T> next = null;
        MySingleLinkedList<T>.Node<T> newHead = null;

        while(current != null){
            next = current.next;
            if(next == null){
                newHead = current;
            }
            //改变current和prev之间的指向
            current.next = prev;
            //让prev、current往后走
            prev = current;
            current = next;
        }
        return newHead;
    }

3.使用两个指针,两个指针的距离为k,当快指针达到结尾,慢指针则指向目标节点

//    查询倒数第k个元素
    public T InverseQuery(int k){
        if(head==null||k<0){
            return null;
        }

        //遍历得到链表元素数
        int count=0;
        Node<T> tmp1=head;
        Node<T> tmp2=head;
       while (tmp1!=null) {
           tmp1=tmp1.next;
           if(count==k){
               tmp2=tmp2.next;
               k++;
           }
           count++;
       }return tmp2.data;

4.使用两个指针分别指向两条链表,然后比较两个指针的data域指针进行相应移动

public  <T extends Comparable<T>>MySingleLinkedList<T>.Node<T> combine(MySingleLinkedList<T>.Node<T> head1,MySingleLinkedList<T>.Node<T> head2){
        MySingleLinkedList<T>.Node<T> tmp1=head1;
        MySingleLinkedList<T>.Node<T> tmp2=head2;
        MySingleLinkedList<T>.Node<T> current =null;
        MySingleLinkedList<T>.Node<T> newHead =null;
        while (true) {
            if (tmp1.data.compareTo(tmp2.data)>0) {

                current=tmp2;
                tmp2=tmp2.next;
            }else {

                current=tmp1;
                tmp1=tmp1.next;
            }
            if(tmp1==null){
                current.next=tmp2;
                break;
            }else if(tmp2==null){
                current.next=tmp1;
                break;
            }
        }return newHead;

    }

5.现在pos后插入结点再交换他们的数据域则实现前插入

 public boolean insert(MySingleLinkedList<T> list ,MySingleLinkedList<T>.Node<T> pos,Node<T> node ){
        if(pos==null){
            return false;
        }
        //在pos后插入
        node.next=pos.next;
        pos.next=node;
        //交换数据
        node.data=pos.data;
        return true;

    }

6.(1)可以借助栈进行实现结点顺序倒置,然后出栈比较,如果两个栈的栈顶元素不同则上次出栈的元素则为相交节点

 public static <T extends Comparable<T>> MySingleLinkedList<T>.Node<T> crosspoint(MySingleLinkedList<T> list1,MySingleLinkedList<T> list2){
        Stack stack1= new Stack();
        Stack stack2= new Stack();
        MySingleLinkedList<T>.Node<T> tmp1=list1.head;
        MySingleLinkedList<T>.Node<T> tmp2=list2.head;
        MySingleLinkedList<T>.Node<T> node=null;
        //所有节点入栈
        while (tmp1!=null){
            stack1.push(tmp1);
            tmp1=tmp1.next;
        }
        while (tmp2!=null){
            stack2.push(tmp2);
            tmp2=tmp2.next;
        }
       //出栈比较
        while (!stack1.empty()||!stack2.empty()){
            if(stack1.peek()==stack2.peek()){
                node=(MySingleLinkedList<T>.Node<T>) stack1.peek();
                stack1.pop();
                stack2.pop();
            }else{
                return node;
            }
        }return null;

    }

(2)同样可以使用快慢指针,让长链表使用快指针,短链表使用慢指针,当两个长度相同时,两个指针一起走,知道遇到目标节点。

  public  <T extends Comparable<T>> MySingleLinkedList<T>.Node<T> crosspoint(MySingleLinkedList<T> list1,MySingleLinkedList<T> list2){
        MySingleLinkedList<T>.Node<T> tmp1=list1.head;
        MySingleLinkedList<T>.Node<T> tmp2=list2.head;
        int count1=0;//记录list1长度
        int count2=0;//记录list2长度
        while (tmp1!=null){
            tmp1=tmp1.next;
            count1++;
        }
        while (tmp2!=null){
            tmp2=tmp2.next;
            count2++;
        }
        tmp1=list1.head;//重置指针
        tmp2=list2.head;
        if(count1>count2){//让长链表的指针先走
            while (tmp1!=tmp2){//两个未遍历的链表长度相同,慢指针开始走
                tmp1=tmp1.next;
                if(count1==count2){
                    tmp2=tmp2.next;
                    count2--;
                }
                count1--;
            }
        }else {
        while (tmp1!=tmp2){
            tmp2=tmp2.next;
            if(count1==count2){
                tmp1=tmp1.next;
                count1--;
            }
            count2--;
        }
        }return tmp1;
    }

7.借助数组对已经遍历过的结点存储然后,和后面遍历的结点比较,如果后面遍历的结点在数组中,则此结点为循环的入口结点。

  public  <T extends Comparable<T>> MySingleLinkedList<T>.Node<T> containRing( MySingleLinkedList<T>.Node<T> head){
        MySingleLinkedList<T>.Node<T> tamp=head;
        MyarrayList<MySingleLinkedList<T>.Node<T>> arr=new MyarrayList();
//数组存储,此处调用了自己的数组类进行存储。也可以用调用系统数组类 
//ArrayList<MySingleLinkedList<T>.Node<T>> arr=new ArrayList<>();
        while (!arr.contains(tamp)){
            arr.addTail(tamp);//存进数组
            tamp=tamp.next;
            if(tamp==null){return null;}//无环返回null
        }return tamp;
    }

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值