zoukankan      html  css  js  c++  java
  • 4.单向链表的常见题型

      本篇主要是单向链表题型的实战,比如反转单向链表、查找单向链表的中间节点、判断一个链表是否有环、合并两个有序链表、判断一个单向链表是否是回文链表。

    /**
     * Node为链表结点对象
     */
    class Node {
        public Integer data;
        public Node next;
        public Node(Integer data){
            this.data = data;
        }
    }
    public class LinkedListUtil {
        /**
         * 反转一个单向链表
         * 思路:申请两个变量(指针)pre、cur,pre指向null,cur指向头结点,cur充当临时变量保存着当前操作结点的下一结点
         * @param head
         * @return
         */
        public static Node reverseList(Node head){
            Node pre = null;
            Node cur = head;
            while(cur != null){
                cur = head.next;
                head.next = pre;
                pre = head;
                head = cur;
            }
            return pre;
        }
    
        /**
         * 获得链表的中间节点,若是单节点链表则返回头结点
         * 思路:申请两个变量(指针)pre、cur,pre指向头结点,cur指向头结点的下一个结点,然后pre每次走一步,cur每次走两步,当cur为null或者cur的下一结点为null则此时pre即为中间节点
         * @param head
         * @return
         */
        public static Node getMiddleNode(Node head) {
            if(head == null) {
                return head;
            }
            Node pre = head;
            Node cur = head.next;
            while(cur != null && cur.next != null){
                pre = pre.next;
                cur = cur.next.next;
            }
            return pre;
        }
    
        /**
         * 判断一个链表是否有环
         * 思路:申请两个变量(指针)pre、cur指向头结点,pre每次走一步,cur每次走两步,若pre等于cur则说明有环
         * @param head
         * @return
         */
        public static boolean isCircle(Node head) {
            Node pre = head;
            Node cur = head;
            while(cur != null && cur.next != null){
                pre=pre.next;
                cur=cur.next.next;
                if(pre == cur){
                    return true;
                }
            }
            return false;
        }
    
        /**
         * 合并两个有序链表为一个升序链表
         *
         * @param head1 有序链表1的头节点
         * @param head2 有序链表2的头节点
         * @return
         */
        public static Node merageOrderedList(Node head1, Node head2) {
            if (head1 == null) {
                return head2;
            }
            if (head2 == null) {
                return head1;
            }
            Node temp1 = head1;
            Node temp2 = head2;
            Node tempHead1 = head1;
            Node tempHead2 = head2;
    
            /*判断链表1是否升序,若不是则反转链表1*/
            while(temp1 != null && temp1.next != null){
                if(temp1.data > temp1.next.data){
                    tempHead1 = reverseList(tempHead1);
                    break;
                }
                temp1 = temp1.next;
            }
            /*判断链表2是否升序,若不是则反转链表2*/
            while(temp2 != null && temp2.next != null){
                if(temp2.data > temp2.next.data){
                    tempHead2 = reverseList(tempHead2);
                    break;
                }
                temp2 = temp2.next;
            }
            //用变量head保存合并后有序链表的头节点
            Node head = null;
            if(tempHead1.data < tempHead2.data){
                head = tempHead1;
                tempHead1 = tempHead1.next;
            }else {
                head = tempHead2;
                tempHead2 = tempHead2.next;
            }
            Node cur = head;
            /*执行合并两个链表*/
            while(tempHead1 != null && tempHead2 != null){
                if(tempHead1.data < tempHead2.data){
                    cur.next= tempHead1;
                    tempHead1= tempHead1.next;
                    cur = cur.next;
                }else{
                    cur.next = tempHead2;
                    tempHead2 = tempHead2.next;
                    cur = cur.next;
                }
            }
            /*执行合并操作结束后,若其中一个链表不为空则将该链表接到合并链表之后*/
            if(tempHead1!= null){
                cur.next = tempHead1;
            }
            if(tempHead2!= null){
                cur.next = tempHead2;
            }
            return head;
        }
    
        /**
         * 判断一个单向链表是否为回文链表
         * 思路:反转后半部分链表,然后与前半部分比对,若有不同则不是回文链表,否则是回文链表,然后反转链表复原并拼接到前半部分
         * @param head
         * @return
         */
        public static boolean isPalindrome(Node head){
            if(head == null || head.next == null){
                return false;
            }
            boolean flag = true;
            //找到链表的中间节点
            Node pre = getMiddleNode(head);
            //反转后半部分的链表
            Node reverseHead = reverseList(pre.next);
            //用cur临时存储一份反转链表的头结点
            Node cur = reverseHead;
            Node helpHead = head;
            while (cur != null){
                if(!cur.data.equals(helpHead.data)){
                    flag = false;
                    break;
                }
                cur = cur.next;
                helpHead = helpHead.next;
            }
            pre.next = reverseList(reverseHead);
            return flag;
        }
    
        public static void main(String[] args){
            Node head = new Node(1);
            head.next = new Node(2);
            head.next.next = new Node(3);
            head.next.next.next = new Node(4);
            boolean isCircle = isCircle(head);
            boolean palindrome = isPalindrome(head);
            Node middle = getMiddleNode(head);
    
            System.out.println("是否为环:" + isCircle);
            System.out.println("是否是回文串"+palindrome);
            System.out.println("中间节点:" + middle.data);
    
    //        System.out.println();
    //        Node reverse = reverseList(head);
    //        while (reverse != null){
    //            System.out.print(reverse.data + "	");
    //            reverse = reverse.next;
    //        }
    //        System.out.println();
    //        Node root = new Node(3);
    //        root.next = new Node(5);
    //        Node mearge = merageOrderedList(head,reverse);
    //        while(mearge != null) {
    //            System.out.print(mearge.data + "	");
    //            mearge = mearge.next;
    //        }
    //        Node ress = reverseList(head);
            Node test =  new Node(1);
            test.next = test;
            System.out.println(isCircle(test));
        }
    }
  • 相关阅读:
    双系统中ubuntu的安装方法
    Android JNI和NDK学习(05)JNI真机调试
    Android JNI和NDK学习(04)NDK调试方法
    Intent总结01 Intent的结构
    Android JNI和NDK学习(07)JNI的常用API
    Android JNI和NDK学习(01)搭建NDK开发环境
    Android JNI和NDK学习(02)静态方式实现JNI
    Intent总结05 extra属性
    Intent总结06 category属性
    Android控件之TextView
  • 原文地址:https://www.cnblogs.com/quxiangxiangtiange/p/12050523.html
Copyright © 2011-2022 走看看