zoukankan      html  css  js  c++  java
  • Java链表基础

    这次来学习下单链表的一些常见操作,链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

    创建链表

    public class test {
        public static void main(String[] args) {
             int[] arr = {5,2,7,4,9,3,1};
             SingleLinkedList singleLinkedList = new SingleLinkedList();
             for(int i=0;i<arr.length;i++){
                 singleLinkedList.add(arr[i]);
             }
             singleLinkedList.deleteNode(1);
             singleLinkedList.printLink();
             System.out.println();
             //int len = singleLinkedList.length();
             //System.out.println(len);
        }
    }
    
    class SingleLinkedList{
        public Node head = new Node();  //head为头节点不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用
        
        class Node{
            public int value;
            public Node next;
            public Node() {}
            public Node(int value) {
                this.value = value;
                this.next = null;
            }
        }
        
        public void add(int value) {//增加节点 尾插法
            if(head.next == null) {
                head.next = new Node(value);
                return;
            }
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
            }
            tempNode.next = new Node(value);
        }
        
        public void printLink() {//遍历链表
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
                System.out.print(tempNode.value+" ");
            }
        }
        
        public void deleteNode(int value) {//根据值删除节点
            Node tempNode = head;
            while(tempNode.next!=null) {
                if(tempNode.next.value == value) {
                    tempNode.next = tempNode.next.next;
                }else {
                    tempNode = tempNode.next;
                }
            }
        }
        
        public int length(){
            int length = 0;
            Node temp = head;
            while (temp.next!=null){
                length++;
                temp = temp.next;
            }
            return length;
        }
    }

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

    翻转链表

    public class test {
        public static void main(String[] args) {
             int[] arr = {5,2,7,4,9,3,1};
             SingleLinkedList singleLinkedList = new SingleLinkedList();
             for(int i=0;i<arr.length;i++){
                 singleLinkedList.add(arr[i]);
             }
             singleLinkedList.reverseList();
             singleLinkedList.printLink();
        }
    }
    
    class SingleLinkedList{
        public Node head = new Node();  //head为头节点不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用
        
        class Node{
            public int value;
            public Node next;
            public Node() {
                this.next = null;
            }
            public Node(int value) {
                this.value = value;
                this.next = null;
            }
        }
        
        public void add(int value) {//增加节点 尾插法
            if(head.next == null) {
                head.next = new Node(value);
                return;
            }
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
            }
            tempNode.next = new Node(value);
        }
        
        public void printLink() {//遍历链表
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
                System.out.print(tempNode.value+" ");
            }
        }
        
        public void reverseList() {
            Node preNode = null;
            Node curNode = head;
            while(curNode!=null) {
                Node tempNode = curNode.next;
                curNode.next = preNode;
                preNode = curNode;
                curNode = tempNode;
            }
            Node newHeadNode = new Node();
            newHeadNode.next = preNode;
            head = newHeadNode;
        }
        
    }

    中间元素

    public class test {
        public static void main(String[] args) {
             int[] arr = {5,2,7,4,9,3,1};
             SingleLinkedList singleLinkedList = new SingleLinkedList();
             for(int i=0;i<arr.length;i++){
                 singleLinkedList.add(arr[i]);
             }
             int midvalue = singleLinkedList.findMiddle();
             System.out.println(midvalue);
        }
    }
    
    class SingleLinkedList{
        public Node head = new Node();  //head为头节点不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用
        
        class Node{
            public int value;
            public Node next;
            public Node() {
                this.next = null;
            }
            public Node(int value) {
                this.value = value;
                this.next = null;
            }
        }
        
        public void add(int value) {//增加节点 尾插法
            if(head.next == null) {
                head.next = new Node(value);
                return;
            }
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
            }
            tempNode.next = new Node(value);
        }
        
        public int findMiddle(){
            Node slowNode = head;
            Node fastNode = head;
            while(fastNode!=null&&fastNode.next!=null) {
                fastNode = fastNode.next.next;
                slowNode = slowNode.next;
            } 
            return slowNode.value;
        }
    }

    运行如下:
    在这里插入图片描述

    判断是否为循环链表

    public class test {
        public static void main(String[] args) {
             int[] arr = {5,2,7,4,9,3,1};
             SingleLinkedList singleLinkedList = new SingleLinkedList();
             for(int i=0;i<arr.length;i++){
                 singleLinkedList.add(arr[i]);
             }
             Boolean hasCycle = singleLinkedList.hasCycle();
             System.out.println(hasCycle);
        }
    }
    
    class SingleLinkedList{
        public Node head = new Node();  //head为头节点不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用
        
        class Node{
            public int value;
            public Node next;
            public Node() {
                this.next = null;
            }
            public Node(int value) {
                this.value = value;
                this.next = null;
            }
        }
        
        public void add(int value) {//增加节点 尾插法
            if(head.next == null) {
                head.next = new Node(value);
                return;
            }
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
            }
            tempNode.next = new Node(value);
        }
        
        public void printLink() {//遍历链表
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
                System.out.print(tempNode.value+" ");
            }
        }
        
        public boolean hasCycle() {
             if(head == null) {
                 return false;
             }
             Node slowNode = head;
             Node fastNode = head;
             while(slowNode!=null&&fastNode!=null&&fastNode.next!=null) {
                 slowNode = slowNode.next;
                 fastNode = fastNode.next.next;
                 if(slowNode == fastNode) {
                     return true;
                 }
             }
             return false;
        }    
    }

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

    链表排序

    public class test {
        public static void main(String[] args) {
             int[] arr = {5,2,7,4,9,3,1};
             SingleLinkedList singleLinkedList = new SingleLinkedList();
             for(int i=0;i<arr.length;i++){
                 singleLinkedList.add(arr[i]);
             }
             singleLinkedList.sortList();
             singleLinkedList.printLink();
        }
    }
    
    class SingleLinkedList{
        public Node head = new Node();  //head为头节点不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用
        
        class Node{
            public int value;
            public Node next;
            public Node() {
                this.next = null;
            }
            public Node(int value) {
                this.value = value;
                this.next = null;
            }
        }
        
        public void add(int value) {//增加节点 尾插法
            if(head.next == null) {
                head.next = new Node(value);
                return;
            }
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
            }
            tempNode.next = new Node(value);
        }
        
        public void printLink() {//遍历链表
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
                System.out.print(tempNode.value+" ");
            }
        }
        
        public void sortList() {
            quickSort(head, null);
        }
    
        private void quickSort(Node low, Node high) {
            if(low == high) {
                return;
            }
            Node pt = partition(low,high);
            quickSort(low,pt);
            quickSort(pt.next,high);
        }
    
        private Node partition(Node low, Node high) {
            int pivotKey = low.value;
            Node p1 = low; Node p2 = low.next;
            while(p2!=high) {
                if(p2.value < pivotKey) {
                    p1 = p1.next;
                    
                    int temp = p1.value;
                    p1.value = p2.value;
                    p2.value = temp;
                }
                p2 = p2.next;
            }
            if(p1!=head) {
                int temp = p1.value;
                p1.value = low.value;
                low.value = temp;
            }
            return p1;
        }
    }

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

    合并两个已排序链表

    public class test {
        public static void main(String[] args) {
             int[] arr1 = {1,4,7};
             int[] arr2 = {2,3,5};
             SingleLinkedList singleLinkedList1 = new SingleLinkedList();
             SingleLinkedList singleLinkedList2 = new SingleLinkedList();
             for(int i=0;i<arr1.length;i++){
                 singleLinkedList1.add(arr1[i]);
             }
             for(int i=0;i<arr2.length;i++){
                 singleLinkedList2.add(arr2[i]);
             }
             Node newNode = singleLinkedList1.merge(singleLinkedList1.head.next,singleLinkedList2.head.next);
             while(newNode!=null) {
                 System.out.print(newNode.value+" ");
                 newNode = newNode.next;
             }
        }
    }
    class Node{
        public int value;
        public Node next;
        public Node() {
            this.next = null;
        }
        public Node(int value) {
            this.value = value;
            this.next = null;
        }    
    }
    
    class SingleLinkedList{
        public Node head = new Node();  //head为头节点不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用
        public void add(int value) {//增加节点 尾插法
            if(head.next == null) {
                head.next = new Node(value);
                return;
            }
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
            }
            tempNode.next = new Node(value);
        }
        
        public Node merge(Node head1,Node head2) {
            if(head1 == null){
                return head2;
            }
            if(head2 == null){
                return head1;
            }
            Node newhead = null;
            if(head1.value <= head2.value){
                newhead = head1;
                newhead.next = merge(head1.next,head2);
            }else{
                newhead = head2;
                newhead.next = merge(head1,head2.next);
            }
            return newhead;
        }
        
    }

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

    删除倒数第N个节点

    public class test {
        public static void main(String[] args) {
             int[] arr = {5,2,7,4,9,3,1};
             SingleLinkedList singleLinkedList = new SingleLinkedList();
             for(int i=0;i<arr.length;i++){
                 singleLinkedList.add(arr[i]);
             }
             singleLinkedList.removeNthFromEnd(2);
             singleLinkedList.printLink();
        }
    }
    
    class SingleLinkedList{
        public Node head = new Node();  //head为头节点不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用
        
        class Node{
            public int value;
            public Node next;
            public Node() {
                this.next = null;
            }
            public Node(int value) {
                this.value = value;
                this.next = null;
            }
        }
        
        public void add(int value) {//增加节点 尾插法
            if(head.next == null) {
                head.next = new Node(value);
                return;
            }
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
            }
            tempNode.next = new Node(value);
        }
        
        public void printLink() {//遍历链表
            Node tempNode = head;
            while(tempNode.next!=null) {
                tempNode = tempNode.next;
                System.out.print(tempNode.value+" ");
            }
        }
        
        public void removeNthFromEnd(int n) {
            if(n<=0) {
                return;
            }
            Node dummyNode = head.next;
            Node preDeleteNode = head;
            
            for(int i=0;i<n;i++) {
                if(dummyNode == null) {
                    return;
                }
                dummyNode = dummyNode.next;
            }
            while(dummyNode!=null) {
                dummyNode = dummyNode.next;
                preDeleteNode = preDeleteNode.next;
            }
            preDeleteNode.next = preDeleteNode.next.next;
        }
    }

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

    判断两个链表是否相交

    public Node getIntersectionNode(Node headA, Node headB) {
        if (headA == null || headB == null) {
            return null;
        }
    
        Node currA = headA;
        Node currB = headB;
        int lengthA = 0;
        int lengthB = 0;
    
        // 让长的先走到剩余长度和短的一样
        while (currA != null) {
            currA = currA.next;
            lengthA++;
        }
        while (currB != null) {
            currB = currB.next;
            lengthB++;
        }
    
        currA = headA;
        currB = headB;
        while (lengthA > lengthB) {
            currA = currA.next;
            lengthA--;
        }
        while (lengthB > lengthA) {
            currB = currB.next;
            lengthB--;
        }
        
        // 然后同时走到第一个相同的地方
        while (currA != currB) {
            currA = currA.next;
            currB = currB.next;
        }
        // 返回交叉开始的节点
        return currA;
    }
  • 相关阅读:
    CDM业务单据,表体单价列赋值所需要注意的问题
    用友CDM系统,将货位间商品移库单(一步)修改为内调出入库单(一步)方法使用
    用友CDM系统“货位间商品移库单(一步)”表体增加“货位可用数量”字段,根据表头的选择的货位自动带出数值
    用友CDM系统期初导入商品资料经验
    SSIS典型应用场景分析
    sql2000执行sql2005导出的数据脚本时出现“提示含有超过64K限度的行”(转)
    将两个不同格式的XML文件,进行节点对照,并生成一个用于对照功能的XML
    winform 根据NAME查找控件
    Nginx服务配置编写
    Nginx安装部署实例
  • 原文地址:https://www.cnblogs.com/coder-ahao/p/14217220.html
Copyright © 2011-2022 走看看