【数据结构与算法】3、虚拟头节点、动态数组的缩容、动态数组和单链表的复杂度、数组的随机访问

简介: 【数据结构与算法】3、虚拟头节点、动态数组的缩容、动态数组和单链表的复杂度、数组的随机访问


一、虚拟头节点

🌼 为了让代码更加精简,统一所有节点的处理逻辑,可以在最前面增加一个虚拟的头节点(不存储数据)

修改 node(int) 方法:

/**
     * 返回 index 位置的节点
     */
    private Node<E> node(int index) {
        rangeCheck(index);
        // 从虚拟头节点的下一个节点开始寻找
        Node<E> moveNode = first.next;
        for (int i = 0; i < index; i++) {
            moveNode = moveNode.next;
        }
        return moveNode;
    }

修改添加和删除方法:

@Override
    public void add(int index, E element) {
        rangeCheck4Add(index);
        // 拿到【index - 1】位置的节点
        Node<E> prev = (index == 0) ? first : node(index - 1);
        prev.next = new Node<>(element, prev.next);
        size++;
    }
@Override
    public E remove(int index) {
        rangeCheck(index);
        Node<E> prev = (index == 0) ? first : node(index - 1);
        Node<E> node = prev.next;
        prev.next = node.next;
        size--;
        return node.element;
    }

二、数组的随机访问

🎉数组的随机访问速度非常快

🎉elements[n] 的效率与 n 是多少无关

三、动态数组、链表复杂度分析

🎉 这里的链表是单链表

四、动态数组 add(E element) 复杂度分析

🎉 扩容操作不是每次都会发生

  • 什么情况下适合使用均摊复杂度?
    🎉经过连续的多次复杂度比较低的情况后,出现个别复杂度比较高的情况

五、动态数组的缩容

🎁 如果内存使用比较紧张,动态数组有比较多的剩余空间,可以考虑进行缩容操作

🎁 比如剩余空间占总容量的一半时,就进行缩容(size 大于总容量的一半的时候进行缩容)

🎁 缩容操作在动态数组的删除方法中进行

private void trim() {
       int oldCapacity = elements.length;
       int halfCapacity = oldCapacity >> 1;
       // size 大于总容量的一半, 总容量小于等于默认容量的时候不缩容
       if (size >= halfCapacity || oldCapacity <= DEFAULT_CAPACITY) return;
       E[] newElements = (E[]) new Object[halfCapacity];
       for (int i = 0; i < size; i++) {
           newElements[i] = elements[i];
       }
       elements = newElements;
       System.out.println(oldCapacity + "缩容为" + halfCapacity);
   }

🎁 如果扩容倍数、缩容时机设计不得当,有可能会导致复杂度震荡

相关文章
|
1月前
|
存储 缓存 算法
数据结构-链表(一)
链表(Linked List)是一种常见的数据结构,用于存储和组织数据。与数组不同,链表的元素(节点)在内存中不必连续存储,而是通过指针链接在一起。 链表由多个节点组成,每个节点包含两部分:数据(存储实际的元素值)和指针(指向下一个节点的引用)。链表的第一个节点称为头节点,最后一个节点称为尾节点,尾节点的指针通常指向空值(null)。
31 1
|
1月前
|
存储 算法
数据结构与算法:复杂度
数据结构: 数据结构是用于存储和组织数据的方式,以便可以有效地访问和修改数据。不同的数据结构适用于不同类型的应用,并且具体的数据结构可以大幅影响程序的性能。数据结构分为两大类:线性数据结构和非线性数据结构。 算法: 算法是完成特定任务的一系列操作步骤,是解决问题的明确规范。算法的效率通常通过时间复杂度和空间复杂度来评估,即算法执行所需的时间和空间资源。
|
1月前
|
存储 C++
数据结构第六弹---带头双向循环链表
数据结构第六弹---带头双向循环链表
|
3天前
|
存储 C语言
数据结构基础:双链表结构、实现
数据结构基础:双链表结构、实现
|
13天前
数据结构—链表(超详细)(山东大学)(数据结构实验三)
数据结构—链表(超详细)(山东大学)(数据结构实验三)
数据结构|双向链表|带头结点|头插|尾插|尾删|头删
数据结构|双向链表|带头结点|头插|尾插|尾删|头删
|
16天前
数据结构--链表刷题(一)快慢指针(上)
数据结构--链表刷题(一)快慢指针
16 0
|
25天前
|
缓存 算法 搜索推荐
【数据结构】链表(单链表与双链表实现+原理+源码)
【数据结构】链表(单链表与双链表实现+原理+源码)
|
29天前
|
存储 编译器 C语言
【数据结构】深入浅出理解链表中二级指针的应用
【数据结构】深入浅出理解链表中二级指针的应用
29 0
|
1月前
|
存储 算法 Serverless
【软件设计师备考 专题 】数据结构深度解析:从数组到图
【软件设计师备考 专题 】数据结构深度解析:从数组到图
56 0