前言

链表:一种在物理上非连续、非顺序的数据结构,由若干节点所组成。
链表常用的有单向链表双向链表,链表的第一个节点称为头节点,最后一个节点称为尾节点,尾节点的next指针指向空:
TIM截图20191127214302.png
TIM截图20191127214440.png
另外,数组在内存中的存储方式是顺序存储,而链表在内存中的存储方式是随机存储
下面采用java代码对链表实现以下操作:

  1. 查找节点
  2. 更新节点
  3. 插入节点
  4. 删除元素

代码实现

package 第二章;

public class No2_2 {
    /**
     * 节点类,data:节点中的数据;next:指向下一个节点的指针next
     */
    private static class Node{
        int data;
        Node next;
        // 初始化函数
        public Node(int data){
            this.data = data;
        }
    }
    
    static class MyLinkedList{
        // 创建头节点指针
        private Node head;
        // 创建尾节点指针
        private Node last;
        // 链表的实际长度
        private int size;

        /**
         * 插入函数
         * @param data 要插入的数据
         * @param index 要插入的位置
         * @throws Exception
         */
        public void insert(int data, int index) throws Exception{
            if (index < 0 || index > size){
                throw new IndexOutOfBoundsException("超出链表节点范围");
            }
            // 创建插入节点,将data作为参数初始化节点
            Node insertNode = new Node(data);
            if (size == 0){
                // 若链表为空,将插入节点作为头节点和尾节点
                head = insertNode;
                last = insertNode;
            }else if (index == 0){
                // 若插入的位置是头部
                insertNode.next = head;
                head = insertNode;
            }else if (size == index){
                // 若插入的位置是尾部
                last.next = insertNode;
                last = insertNode;
            }else{
                // 若插入的位置是中间
                // 先得到该位置的前一个节点
                Node prevNode = query(index-1);
                // 将插入节点的指针指向要插入位置的节点
                insertNode.next = prevNode.next;
                // 将前一个位置节点的指针指向插入节点
                prevNode.next = insertNode;
            }
            // 插入之后,链表大小+1
            size++;
            output();
        }

        /**
         * 查找函数
         * @param index 要查找的元素的位置
         */
        public Node query(int index) throws Exception{
            if (index < 0 || index >= size){
                throw new IndexOutOfBoundsException("超出链表节点范围!");
            }
            // 创建一个中间节点,并指向头节点
            Node temp = head;
            for(int i=0;i<index;i++){
                // 遍历链表,每次将当前节点指向的节点赋值给temp
                temp = temp.next;
            }
            System.out.println("节点查询成功");
            return temp;
        }

        /**
         * 删除节点
         * @param index 要删除的位置
         * @throws Exception
         */
        public void delete(int index) throws Exception{
            if (index < 0 || index >= size){
                throw new IndexOutOfBoundsException("超出链表节点范围!");
            }
            if (index == 0){
                // 删除头节点
                head = head.next;
            }else if (index == (size-1)){
                // 删除尾节点
                Node prevNode = query(index-1);
                // 首先把尾节点的前一个节点的指针指向空
                prevNode.next = null;
                // 然后将该节点赋值给尾节点
                last = prevNode;
            }else{
                Node prevNode = query(index-1);
                // 将前一个节点的指针指向下下个节点
                prevNode.next = prevNode.next.next;
            }
            System.out.println("节点删除成功");
            size--;
            output();
        }

        /**
         * 更新节点数据
         * @param data 要更新的数据
         * @param index 要更新的位置
         * @throws Exception
         */
        public void updata(int data, int index) throws Exception{
            if (index < 0 || index >= size){
                throw new IndexOutOfBoundsException("超出链表节点范围!");
            }
            Node node = query(index);
            node.data = data;
            System.out.println("节点数据修改成功");
            output();
        }

        /**
         * 输出链表
         */
        public void output(){
            Node temp = head;
            for (int i=0;i<size; i++){
                System.out.println("第" + (i+1) + "个节点:" + temp.data);
                temp = temp.next;
            }
            System.out.println("==========================");
        }
    }

    public static void main(String[] args) throws Exception{
        MyLinkedList myLinkedList = new MyLinkedList();
        // 插入节点
        myLinkedList.insert(3,0);
        myLinkedList.insert(4, 1);
        myLinkedList.insert(9,2);
        myLinkedList.insert(7,3);
        myLinkedList.insert(5,4);
        // 查询节点
        Node temp = myLinkedList.query(1);
        System.out.println("该节点数据为" + temp.data);
        // 更新节点
        myLinkedList.updata(2,3);
        // 删除节点
        myLinkedList.delete(2);
    }
}

小结

链表数组都是线性的数据结构。
数组的优点在于能够快速定位元素,适合对于读操作多,写操作较少的场景。
链表的优点在于能够灵活地进行插入和删除操作,适合需要在尾部频繁插入或者删除元素的场景。

最后修改:2020 年 01 月 25 日
如果觉得我的文章对你有用,请随意赞赏