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

动态数据列表类的不变式

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

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

相关推荐
Savior`L6 小时前
二分算法及常见用法
数据结构·c++·算法
甄心爱学习8 小时前
CSP认证 备考(python)
数据结构·python·算法·动态规划
kyle~9 小时前
排序---常用排序算法汇总
数据结构·算法·排序算法
有时间要学习9 小时前
面试150——第二周
数据结构·算法·leetcode
freedom_1024_10 小时前
红黑树底层原理拆解
开发语言·数据结构·b树
liu****10 小时前
3.链表讲解
c语言·开发语言·数据结构·算法·链表
minji...10 小时前
Linux 基础IO(一) (C语言文件接口、系统调用文件调用接口open,write,close、文件fd)
linux·运维·服务器·网络·数据结构·c++
CQ_YM11 小时前
数据结构之栈
数据结构·算法·
xlq2232211 小时前
24.map set(下)
数据结构·c++·算法
立志成为大牛的小牛12 小时前
数据结构——五十四、处理冲突的方法——开放定址法(王道408)
数据结构·学习·程序人生·考研·算法