数据结构与算法篇--结构不变式--动态数组

动态数据列表类的不变式

重点:形式化定义转换成 checkInvariants 代码

DArrayList

DArrayListTest

形式化定义

txt 复制代码
Invariant:
  (1) data != null
  (2) capacity > 0
  (3) 0 <= size <= capacity
  (4) ∀ i ∈ [0, size): data[i] != null
  (5) ∀ i ∈ [size, capacity): data[i] == null
  (6) capacity 仅通过 resize() 成倍增长

checkInvariants源码

java 复制代码
public void checkInvariants() {
    // --- 1. 容量与大小约束检查 ---

    // C1: 容量必须大于 0
    if (capacity <= 0) {
        throw new AssertionError("Invariant Broken: Capacity must be positive (capacity=" + capacity + ")");
    }

    // C2: Size 必须在 [0, capacity] 范围内
    if (size < 0 || size > capacity) {
        throw new AssertionError("Invariant Broken: Size must be between 0 and capacity (size=" + size + ", capacity=" + capacity + ")");
    }

    // --- 2. 数组和数据完整性检查 ---

    // D1: 底层数组必须存在
    if (data == null) {
        throw new AssertionError("Invariant Broken: Internal array 'data' must not be null.");
    }

    // D2: 数组的实际长度必须等于记录的 capacity
    if (data.length != capacity) {
        throw new AssertionError("Invariant Broken: data.length (" + data.length + ") does not match recorded capacity (" + capacity + ")");
    }

    // --- 3. 数据填充和空值约束检查 ---

    // 验证有效数据范围 [0, size-1]
    for (int i = 0; i < size; i++) {
        // D3: 有效数据区域 [0, size-1] 不得包含 null
        if (data[i] == null) {
            // 根据您的 add 方法,data[i] 应该是非空的
            throw new AssertionError("Invariant Broken: Element at index " + i + " must not be null (size=" + size + ")");
        }
    }

    // 验证闲置空间范围 [size, capacity-1]
    for (int j = size; j < capacity; j++) {
        // D4: 闲置空间 [size, capacity-1] 必须为 null (防止内存泄漏)
        if (data[j] != null) {
            throw new AssertionError("Invariant Broken: Element at index " + j + " must be null to prevent memory leak (size=" + size + ", capacity=" + capacity + ")");
        }
    }

    InternalIterator it = new InternalIterator();
    int elementsFound = 0;
    while(it.hasNext()) {
        try {
            it.next();
            elementsFound++;
        } catch (NoSuchElementException e) {
            throw new AssertionError("Iterator failed unexpectedly near index " + elementsFound);
        }
    }
    if (elementsFound != size) {
        throw new AssertionError("Iterator found " + elementsFound + " elements, but size is " + size);
    }
}

使用指南

  1. 整合代码:checkInvariants() 方法添加到您的 DArrayList 类定义中。
  2. 插入调用: 在每个修改数组状态的方法(DArrayListaddremove 以及私有方法 resize)的末尾调用 this.checkInvariants();

通过这种方式,每次修改数组后,程序都会进行一次快速的自我验证,确保您的动态扩容和元素移动逻辑没有破坏任何核心不变式。

相关推荐
予枫的编程笔记1 小时前
Redis 核心数据结构深度解密:从基础命令到源码架构
java·数据结构·数据库·redis·缓存·架构
wadesir1 小时前
掌握Rust并发数据结构(从零开始构建线程安全的多线程应用)
数据结构·安全·rust
charliejohn2 小时前
计算机考研 408 数据结构 哈夫曼
数据结构·考研·算法
好易学·数据结构3 小时前
可视化图解算法76:最大子数组和
数据结构·算法·leetcode·面试·动态规划·力扣·笔试
falldeep4 小时前
Pandas入门指南
数据结构·算法·leetcode·pandas
闲看云起5 小时前
Leetcode-day4:从「移动零」到「盛最多水的容器」
数据结构·算法·leetcode·职场和发展
nuowenyadelunwen5 小时前
Harvard CS50 Problems Set 5
数据结构·harvard cs50·树,哈希表,链表
mjhcsp6 小时前
P14795 [JOI 2026 二次预选] 分班 / Class Division
数据结构·c++·算法
girl-07266 小时前
2025.12.29实验题目分析总结
数据结构·算法
sin_hielo6 小时前
leetcode 840
数据结构·算法·leetcode