美文网首页
单链表相关操作

单链表相关操作

作者: 匿名用户_bcc3 | 来源:发表于2018-11-01 17:09 被阅读0次

    在面试中,链表的操作一直是个很常见的考察点,之前也一直觉得链表相关操作很难,但是只要多动手练一练,没有那么难,最怕的就是只看不写,看完就溜。
    链表中常见的操作主要有:

    • 创建一个链表
    • 向链表中添加节点
    • 删除链表中的某个节点
    • 链表翻转的两种方式(递归、非递归)
    • 查找链表的中间节点或者倒数第k个节点
    • 检测链表是否包有环

    code

    package com.program;
    class LinkedList {
        private Node head;
        /**
         * 添加链表节点
         *
         * @param data
         */
        public void addNode(int data) {
            if (head == null) {
                head = new Node(data);
                return;
            }
            Node temp = head;
            while (temp.next != null) {
                temp = temp.next;
            }
            temp.next = new Node(data);
        }
    
        /**
         * 删除链表节点
         *
         * @param index
         */
        public void deleteNode(int index) {
            if (index < 0 || index > getLength() - 1) {
                return;
            }
            Node temp = head;
            if (index == 0) {
                head = head.next;
                return;
            }
            int i = 0;
            while (temp != null && i != index - 1) {
                temp = temp.next;
                i++;
            }
            if (temp.next.next != null) {
                temp.next = temp.next.next;
            } else {
                temp.next = null;
            }
        }
    
        /**
         * 链表翻转:方法1,
         * 主要思路:
         * 把当前节点的下一个节点暂存,作为后面遍历的节点
         * 把当前节点暂存,作为下个节点的next节点,
         */
        public void reverseList() {
            if (head == null || head.next == null) {
                return;
            }
            Node temp = head;
            Node preNode = null;
            while (temp != null) {
                Node nextNode = temp.next;
                if (nextNode == null) {
                    head = temp;
                }
                temp.next = preNode;
                preNode = temp;
                temp = nextNode;
            }
        }
    
        /**
         * 递归方式实现链表翻转,递归的确是难以理解啊。
         *
         * @param head
         * @return
         */
        public Node reverseList2(Node head) {
            if (head == null || head.next == null) {
                return head;
            }
            Node newNode = reverseList2(head.next);
            head.next.next = head;
            head.next = null;
            return newNode;
        }
    
        /**
         * 查找当前单链表的中间节点,
         * 主要思路:
         * 两个指针,一个一次走两步,一个一次走一步,两步结束,一步到中间
         */
        public void searchMidNode() {
            Node temp1 = head;
            Node temp2 = head;
            while (temp2.next != null && temp2.next.next != null) {
                temp2 = temp2.next.next;
                temp1 = temp1.next;
            }
            System.out.println(temp1.node);
        }
    
        /**
         * 查找倒数第k个元素
         * 主要思路:
         * 两个指针,一个先走k步,然后另一个再走,第一个走到头了,over.
         *
         * @param k
         */
        public void findElem(int k) {
            if (k < 0 || k > getLength()) {
                return;
            }
            Node temp1 = head;
            Node temp2 = head;
            int i = 1;
            while (i < k) {
                temp1 = temp1.next;
                i++;
            }
            while (temp1.next != null) {
                temp1 = temp1.next;
                temp2 = temp2.next;
            }
            System.out.println(temp2.node);
    
        }
    
        /**
         * 判断链表是否有环
         * 主要思路,两个不同速度的指针同时出发,如果快指针追上慢指针,那么一定有环了。跑道就是这个道理。
         *
         * @return
         */
        public boolean isLoop() {
            Node fast = head;
            Node slow = head;
            if (head == null || head.next == null) {
                return false;
            }
            while (fast.next != null && fast.next.next != null) {
                fast = fast.next.next;
                slow = slow.next;
                if (fast == slow) {
                    return true;
                }
            }
            return false;
        }
    
        /**
         * 获取链表长度
         *
         * @return
         */
        private int getLength() {
            Node tmp = head;
            int i = 0;
            while (tmp != null) {
                i++;
                tmp = tmp.next;
            }
            return i;
        }
    
        public static void printList(LinkedList linkedList) {
            Node head = linkedList.head;
            Node temp = head;
            while (temp != null) {
                System.out.print(temp.node + " ");
                temp = temp.next;
            }
        }
    
        public Node getHead() {
            return head;
        }
    
        public static void main(String[] args) throws java.lang.Exception {
            System.out.println("zhou'xiang");
            LinkedList listss = new LinkedList();
            listss.addNode(5);
            listss.addNode(4);
            listss.addNode(2);
            listss.addNode(0);
            listss.addNode(1);
            System.out.println("原始链表如下");
            printList(listss);
            System.out.println("\n删除第0个节点之后的链表如下");
            listss.deleteNode(0);
            printList(listss);
            System.out.println("\n翻转之后如下");
            listss.reverseList();
            printList(listss);
            System.out.println("\n再次翻转之后如下");
            listss.reverseList();
            printList(listss);
            System.out.println("\n链表中间值为");
            listss.searchMidNode();
            System.out.println("链表倒数第2个节点为:");
            listss.findElem(2);
            System.out.println("\n递归翻转之后如下:");
            listss.reverseList2(listss.getHead());
            //printList(listss);
        }
    
        class Node {
            int node;
            Node next;
            public Node(int data) {
                this.node = data;
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:单链表相关操作

          本文链接:https://www.haomeiwen.com/subject/swbxxqtx.html