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

动态数据列表类的不变式

重点:形式化定义转换成 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 小时前
FFmpeg 基本数据结构 AVInputFormat 分析
数据结构·c++·ffmpeg·音视频
给大佬递杯卡布奇诺1 小时前
FFmpeg 基本数据结构 AVCodecContext分析
数据结构·c++·ffmpeg·音视频
budingxiaomoli3 小时前
算法--滑动窗口(一)
数据结构·算法
想唱rap5 小时前
C++ list 类的使用
c语言·开发语言·数据结构·c++·笔记·算法·list
仰泳的熊猫7 小时前
LeetCode:773. 滑动谜题
数据结构·c++·算法·leetcode
huangql5208 小时前
JavaScript数据结构实战指南:从业务场景到性能优化
javascript·数据结构·性能优化
hope_wisdom10 小时前
C/C++数据结构之用链表实现栈
c语言·数据结构·c++·链表·
大肘子咒你10 小时前
数字狂潮来袭
数据结构·c++·1024程序员节
岑梓铭11 小时前
《考研408数据结构》第六章(5.1+5.2+5.3树、二叉树、线索二叉树)复习笔记
数据结构·笔记·考研·408·1024程序员节
苏纪云12 小时前
数据结构<C++>——数组
java·数据结构·c++·数组·动态数组