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

动态数据列表类的不变式

重点:形式化定义转换成 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();

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

相关推荐
郝学胜-神的一滴7 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
不知名XL13 小时前
day50 单调栈
数据结构·算法·leetcode
cpp_250115 小时前
P10570 [JRKSJ R8] 网球
数据结构·c++·算法·题解
cpp_250115 小时前
P8377 [PFOI Round1] 暴龙的火锅
数据结构·c++·算法·题解·洛谷
季明洵15 小时前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
only-qi15 小时前
leetcode19. 删除链表的倒数第N个节点
数据结构·链表
cpp_250115 小时前
P9586 「MXOI Round 2」游戏
数据结构·c++·算法·题解·洛谷
浅念-15 小时前
C语言编译与链接全流程:从源码到可执行程序的幕后之旅
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
爱吃生蚝的于勒16 小时前
【Linux】进程信号之捕捉(三)
linux·运维·服务器·c语言·数据结构·c++·学习
数智工坊16 小时前
【数据结构-树与二叉树】4.6 树与森林的存储-转化-遍历
数据结构