跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

数据结构:顺序表的常用方法实现

顺序表(基于数组)的基本实现原理及常用操作方法。内容包括顺序表的初始化、扩容机制、元素增删改查功能的代码实现。重点讲解了在指定位置插入时的元素移动逻辑、数组越界处理、以及内存释放注意事项。提供了完整的 Java 代码示例,涵盖合法性校验、异常抛出及工具类使用,适合初学者理解线性表底层数据结构。

链路追踪发布于 2026/3/27更新于 2026/7/2446 浏览
数据结构:顺序表的常用方法实现

线性表

线性表包括顺序表、链表、栈、队列等,本节重点学习顺序表。

顺序表

顺序表本质是对数组的封装,支持增删改查操作。

顺序表示意图

打印顺序表元素

/**
 * 打印顺序表中的所有元素
 */
@Override
public void display() {
    for (int i = 0; i < usedSize; i++) {
        System.out.println(elem[i] + " ");
    }
    System.out.println();
}

往数组末尾添加元素

/**
 * 添加元素:默认添加到数组的最后位置
 * @param data
 */
@Override
public void add(int data) {
    // 如果满了,要进行扩容
    if (isFull()) {
        // 二倍扩容 -> 拷贝完之后让 elem 指向一个新的数组对象
        elem = Arrays.copyOf(elem, 2 * elem.length);
    }
    // 将元素放入数组中
    elem[usedSize] = data;
    usedSize++;
}

// 判断数组是否满了
@Override
public boolean isFull() {
    return usedSize == elem.length;
}

通过调试可以看到,当数组元素超出其所能承载的容量大小时,可以通过 copyOf 进行扩容,从而将新元素放进去。

在指定位置添加新元素

插入逻辑如下:

  1. 从后往前移动元素。
  2. 将元素放进指定位置,并且更新元素个数。
@Override
public void add(int pos, int data) {
    // 1. pos 位置的判断 -> pos 不能为负的或 pos 不能隔空插元素
    checkPosOfAdd(pos);
    // 2. 如果这个数组是满的,则需要对数组进行扩容才能插入新元素
    isFulling();
    // 3. 先挪动元素,将最后面元素逐个往前挪
    // i >= pos 时元素才会往前移
    for (int i = usedSize - 1; i >= pos; i--) {
        elem[i + 1] = elem[i];
    }
    // 挪完将指定元素插入到位置中
    elem[pos] = data;
    usedSize++;
}

// 1. pos 位置的判断 -> pos 不能为负的或 pos 不能隔空插元素
public void checkPosOfAdd(int pos) {
    if (pos < 0 || pos > usedSize) {
        throw new PosException("pos 位置是" + pos);
    }
}

// 2. 如果这个数组是满的,则需要对数组进行扩容才能插入新元素
public void isFulling() {
    elem = Arrays.copyOf(elem, 2 * elem.length);
}

注意:如果数组已满且未扩容直接插入,会报越界异常。解决方案是在插入前判断是否已满,若满则扩容。

查找当前元素是否存在

/**
 * 查找当前元素是否存在
 * @param toFind
 * @return
 */
@Override
public boolean contains(int toFind) {
    for (int i = 0; i < usedSize; i++) {
        if (elem[i] == toFind) {
            return true;
        }
    }
    return false;
}

如果这里的元素是引用类型,需要通过 equals 进行比较。

查找当前元素的下标

/**
 * 查找当前元素的下标
 * @param toFind
 * @return
 */
@Override
public int indexOf(int toFind) {
    for (int i = 0; i < usedSize; i++) {
        if (elem[i] == toFind) {
            // 如果这里是引用数据类型需要用 equals 进行比较
            return i;
        }
    }
    return -1;
}

获取对应下标对应元素的数值

/**
 * 获取 pos 位置的值
 * @param pos
 * @return
 */
@Override
public int get(int pos) {
    // 1. 判断 pos 合法性
    checkPosGet(pos);
    // 2. pos 为空的异常处理
    if (isEmpty()) {
        throw new EmptyException("数组为空,无法获取元素");
    }
    return elem[pos];
}

// 1. 判断 pos 合法性
public void checkPosGet(int pos) {
    if (pos < 0 || pos >= usedSize) {
        throw new PosException("Pos 不合法,位置是:" + pos);
    }
}

// 2. pos 为空的异常处理 -> 此时 pos 正好符合>=usedSize(为 0) 的情况,算是 1 的一种。
public boolean isEmpty() {
    return usedSize == 0;
}

更新对应下标的元素值

/**
 * 更新 pos 位置的值为 value
 * @param pos
 * @param value
 */
@Override
public void set(int pos, int value) {
    // 1. 检查 pos 位置的合法性
    checkPosOfSet(pos);
    // 2. pos 为空的异常处理
    if (isEmpty()) {
        throw new EmptyException("顺序表为空");
    }
    elem[pos] = value;
}

public void checkPosOfSet(int pos) {
    if (pos < 0 || pos >= usedSize) {
        throw new PosException("Pos 位置不合法位置是:" + pos);
    }
}

获取顺序表的大小

/**
 * 获取顺序表的大小
 * @return
 */
@Override
public int size() {
    return this.usedSize;
}

删除指定元素

/**
 * 删除 toRemove 这个数字
 * 删除指定元素
 * @param toRemove
 */
@Override
public void remove(int toRemove) {
    // 首先,找到元素下标
    // 因为刚刚已经实现过通过元素寻找下标的方法了,现在只要调用这个方法即可找到对应元素的下标
    int index = indexOf(toRemove);
    // 然后,将这个位置前面的元素往后移动覆盖掉即可删除
    for (int i = index; i < usedSize - 1; i++) {
        elem[i] = elem[i + 1];
    }
    usedSize--;
}

释放内存

在源码中通常先将元素置为 null 之后,再将空间置为 0 进行释放。

/**
 * 清空顺序表,防止内存泄漏
 */
@Override
public void clear() {
    usedSize = 0;
}

示例中的数据都是 int 类型不是引用类型,所以如果需要释放内存,直接将其赋值为 0 即可。而对于引用类型由于他们有内存地址所以需要将它们置为 null 才能释放内存。

目录

  1. 线性表
  2. 顺序表
  3. 打印顺序表元素
  4. 往数组末尾添加元素
  5. 在指定位置添加新元素
  6. 查找当前元素是否存在
  7. 查找当前元素的下标
  8. 获取对应下标对应元素的数值
  9. 更新对应下标的元素值
  10. 获取顺序表的大小
  11. 删除指定元素
  12. 释放内存
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 微信 ClawBot 插件接入个人微信及 Windows 安装指南
  • VulnStack 7 红日靶场实战:从外网到域控的全流程渗透
  • Visual C++ Redistributable 安装失败修复指南
  • Django 框架入门:从零开始构建 Web 应用
  • RAG 系统 PDF 解析代码详解:PdfParser 核心流程与优化
  • C++ 基础实战:从循环控制到算法入门
  • Spring AI 基于 MySQL 实现对话持久存储详解
  • AI 产品经理面试指南:核心能力、技术问答与项目实战
  • Retinaface+CurricularFace 基于 Kubernetes StatefulSet 部署方案
  • Android 组件化与插件化架构详解与实践指南
  • 写一个订单簿:C++实现和几个容易踩的坑
  • RAG 技术入门与实战:检索增强生成详解与 PyTorch 实现
  • 高鋒集團與 Web3Labs:資本與生態如何賦能傳統企業 Web3 轉型
  • 2026 年 Python 发展局势:AI 时代的通用基础设施语言
  • Android 中使用 WebRTC 的 AI 辅助开发实战:从搭建到性能优化
  • C++ 模板进阶:特化、萃取与可变参数实战
  • 昆仑万维 Skywork-R1V3 开源:38B 多模态推理模型与高考数学表现
  • AI 大模型学习路径与行业转型指南
  • AI 时代产品经理:智能产品构建新范式与核心能力
  • uv 精准指定 Python 版本的方法与实践

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online