Java数据结构----单链表习题

递归实现逆序输出单链表

我们可以采用递归的方式实现逆序输出单链表的操纵,因为head节点的next节点是指向head的下一个节点,所以我们从头开始遍历链表,并让head往后走,当head.next为空时,此时已经走到链表结尾处,输出节点值。重复以上操作,即可实现链表逆序输出。
代码如下:

 public static <T> void reversePrintList(SingleLinkedList<T>.Node<T> head){
    
    
          //递归终止条件
        if(head==null){
    
    
            //处理办法
            return;
        }
        //提取重复逻辑,缩小问题规模
        reversePrintList(head.next);
        System.out.println(head.data);
    }

逆置单链表

在这道题里我们需要定义三个节点来进行操作,prev用来表示当前节点的上一个节点,current用来表示当前节点,next用来表示当前节点的下一个节点。
当当前节点不为空时,我们开始将当前节点与前一个节点的指向转变,如果next节点为空,那说明已经走到原来链表的末尾位置,此时将当前节点作为逆置后新链表的头节点。
直到当前节点为空,逆置完成。
具体代码:

 public static <T> SingleLinkedList<T>.Node<T> reverseList(SingleLinkedList<T>.Node<T> head){
    
    
        SingleLinkedList<T>.Node<T> prev = null;//当前节点的上一个
        SingleLinkedList<T>.Node<T> current = head;//当前节点
        SingleLinkedList<T>.Node<T> next = null;//当前节点的下一个
        SingleLinkedList<T>.Node<T> newHead = null;//逆置后链表的头节点
        while(current!=null){
    
    
            next = current.next;

            if(next == null){
    
    
                newHead = current;
            }
            //改变当前节点与之前一个节点之间的指向
            current.next = prev;
            prev = current;
            current = next;
        }
        return newHead;
    }

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

对于合并两个有序链表,我们可以先定义一个新链表的头节点和一个临时引用,先进行比较,哪一个链表的首位数小就把那一个作为新链表的头节点。
随后,分别比较两个链表后面数据的大小,借用临时引用,把较小的一个接入新链表。
此时,若一个链表为空,那可将剩下链表这部分的数据直接链入新链表。
代码如下:

    public static <T extends Comparable<T>> SingleLinkedList<T>.Node<T> mergrLinkedList(
            SingleLinkedList<T>.Node<T> head1,SingleLinkedList<T>.Node<T> head2){
    
    
        SingleLinkedList<T>.Node<T> newHead = null;//确定新链表的头节点

        if(head1.data.compareTo(head2.data)<0){
    
    
            newHead = head1;
            head2 = head1.next;
        }else {
    
    
            newHead = head2;
            head2 = head2.next;
        }

        //临时引用在新链表中从前往后去跑
        SingleLinkedList<T>.Node<T> tmp = newHead;

        while (head1!=null&&head2!=null){
    
    
            if(head1.data.compareTo(head2.data)<0){
    
    
                tmp.next = head1;
                head1 = head1.next;
            }else {
    
    
                tmp.next = head2;
                head2 = head2.next;
            }
            tmp = tmp.next;
        }
        if(head1 == null){
    
    
            tmp.next = head2;
        }
        if(head2 == null){
    
    
            tmp.next = head1;
        }
        return newHead;
    }

判断两个链表的相交结点

因为两个链表的长度不同,所以我们先获取两个链表的长度,让长链表的引用先走其插值的长度。
随后,让两个引用同时走,若两个引用相等了,那么说明此时该引用所指向的节点即为相交结点。
代码如下:

public static <T> SingleLinkedList<T>.Node<T> commonNode2(SingleLinkedList<T> list1,
                                    SingleLinkedList<T> list2){
    
    
        if(list1.head == null||list2.head == null) return null;

        //计算两个链表的差值
        int length1 = getlength(list1.head);
        int length2 = getlength(list2.head);

        int lengthDif = Math.abs(length1-length2);

        SingleLinkedList<T>.Node<T> longHead =list1.head;
        SingleLinkedList<T>.Node<T> shortHead =list2.head;

        //长链表先走其差值
        if(length1<length2){
    
    
            longHead = list1.head;
            shortHead = list2.head;
        }

        for(int i=0;i<lengthDif;i++){
    
    
            longHead = longHead.next;
        }

        //长链表和短链表开始同时走,当两个引用的相等的时候,此时该引用所指向的节点就是相交结点
        while (shortHead!=longHead){
    
    
            longHead = longHead.next;
            shortHead = shortHead.next;
        }
        return longHead;
    }

判断单链表是否有环,同时得到环的入口节点是哪个

判断是否有环,我们可以定义两个引用,一个慢引用、一个快引用。
让慢引用一次走两步,慢引用一次走一步。当他们在环中相遇时的节点即为环的入口节点。
代码如下:

    public static  <T> boolean isRing(SingleLinkedList<T> list){
    
    
        //快 、慢引用   快引用一次走两步 慢引用一次走一步
        SingleLinkedList<T>.Node<T> slow = list.head;
        SingleLinkedList<T>.Node<T> fast = list.head;

        while (fast!=null&&slow!=null&&fast.next!=null){
    
    
            if(fast == slow){
    
    
                //表示在环中相遇,fast/slow所指向的节点为相遇节点
                return true;
            }
            slow = slow.next;
            fast = fast.next.next;
        }
        return false;
    }

猜你喜欢

转载自blog.csdn.net/m0_49449205/article/details/110680934