【Java数据结构】初识线性表之一:顺序表

使用Java简单实现一个顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

线性表大致包含如下的一些方法:

public class MyArrayList {

private int\[\] array;

private int size;

// 默认构造方法默认分配空间

SeqList(){ }

// 将顺序表的底层容量设置指定容量

SeqList(int initcapacity){ }

// 新增元素,默认在数组最后新增

public void add(int data) { }

// 在 pos 位置新增元素

public void add(int pos, int data) { }

// 判定是否包含某个元素

public boolean contains(int toFind) { return true; }

// 查找某个元素对应的位置

public int indexOf(int toFind) { return -1; }

// 获取 pos 位置的元素

public int get(int pos) { return -1; }

// 给 pos 位置的元素设为 value

public void set(int pos, int value) { }

//删除第一次出现的关键字key

public void remove(int toRemove) { }

// 获取顺序表长度

public int size() { return 0; }

// 清空顺序表

public void clear() { }

// 打印顺序表

public void display() { }

}

接下来根据上面的方法实现一个 int 类型的顺序表:

java 复制代码
import java.util.Arrays;
public class MyArrayList {
    private int[] elem;
    private int usedSize;
    private static final int DEFAULT_SIZE = 10;
    public MyArrayList(){
        elem = new int[DEFAULT_SIZE];
    }
    public MyArrayList(int initCapacity){
        elem = new int[initCapacity];
    }

    private boolean checkCapacity(){
        if(this.usedSize == elem.length){
            return true;
        }
        return false;
    }

    public void display(){
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(this.elem[i] + " ");
        }
    }
    public void add(int data){
        if(checkCapacity()){
            this.elem = Arrays.copyOf(this.elem,2*elem.length);
        }
        this.elem[this.usedSize] = data;
        this.usedSize++;
        return;
    }
    public void add(int pos,int data){
        if(pos > this.usedSize || pos < 0){
            throw new PosOutOfBoundsException("插入位置错误!");
        }
        if(checkCapacity()){
            this.elem = Arrays.copyOf(this.elem,2*elem.length);
        }
        for (int i = this.usedSize - 1; i >=pos ; i--) {
            elem[i+1] = elem[i];
        }
        this.elem[pos] = data;
        this.usedSize++;
        return;
    }

    public boolean contains(int data){
        for (int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == data){
                return true;
            }
        }
        return false;
    }

    public int indexof(int data){
        for (int i = 0; i < this.usedSize; i++) {
            if(this.elem[i] == data){
                return i;
            }
        }
        return -1;
    }
    public int get(int pos){
        if(pos >= this.usedSize || pos < 0){
            throw new PosOutOfBoundsException("输入的位置错误!");
        }
        return this.elem[pos];
    }
    public void set(int pos,int data){
        if(pos >= this.usedSize || pos < 0){
            throw new PosOutOfBoundsException("输入的位置错误!");
        }
        this.elem[pos] = data;
    }
    public int size(){
        return this.usedSize;
    }
    public void remove(int data){
        if(this.contains(data)){
            int pos = this.indexof(data);
            for (int i = pos; i < this.usedSize - 1; i++) {
                this.elem[pos] = this.elem[pos+1];
            }
            this.usedSize--;
        }else{
            throw new PosOutOfBoundsException("没有该元素");
        }
    }
    public void clear(){
        this.usedSize = 0;
        return;
    }
}

ArrayList简介

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:

  • ArrayList是以泛型方式实现的,使用时必须要先实例化
  • ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
  • ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
  • ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
  • 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
  • CopyOnWriteArrayList
  • ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

ArrayList如何使用

ArrayList的构造方法

ArrayList中的构造方法:

ArrayList();//无参构造

ArrayList(Collection<? extends E> c);//利用其他 Collection 构建 ArrayList

ArrayList(int initialCapacity);//指定顺序表初始容量

代码示例:

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>();//无参构造
        List<Integer> list2 = new ArrayList<>(10);//指定容量
        list2.add(1);
        list2.add(2);
        list2.add(3);
        List<Integer> list3 = new ArrayList<>(list2);//利用其他 Collection 构建 ArrayList
    }
}

ArrayList常见操作

尾插

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();//无参构造
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list);
    }
}

将元素插入到指定位置

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(1,4);
        System.out.println(list);
    }
}

尾插另一个顺序表中的元素

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer>  list1 = new ArrayList<>();
        list1.add(4);
        list1.add(5);
        list1.add(6);
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.addAll(list1);
        System.out.println(list);
    }
}

删除指定位置元素

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.remove(1);
        System.out.println(list);
    }
}

删除指定数据

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.remove(new Integer(2));
        System.out.println(list);
    }
}

获取指定位置元素

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list.get(1));
    }
}

将指定位置元素设置为新数据

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.set(1,4);
        System.out.println(list);
    }
}

清空顺序表

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.clear();
        System.out.println(list);
    }
}

判断一个元素是否在顺序表中

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list.contains(2));
        System.out.println(list.contains(4));
    }
}

返回第一个指定元素所在下标

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(1);
        System.out.println(list.indexOf(1));
    }
}

返回最后一个指定元素所在下标

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(1);
        System.out.println(list.lastIndexOf(1));
    }
}

截取部分list

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(list.subList(0,2));
    }
}

遍历 ArrayList 的三种方法

ArrayList 可以使用三方方式遍历:for循环+下标、foreach增强循环、使用迭代器

java 复制代码
public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        //使用fori遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i));
        }
        System.out.println();
        //使用foreach遍历
        for(Integer integer:list){
            System.out.print(integer);
        }
        System.out.println();
        //使用迭代器遍历
        Iterator<Integer> it = list.listIterator();
        while(it.hasNext()){
            System.out.print(it.next());
        }
    }
}

运行结果:

ArrayList的场景使用

洗牌算法

将一副扑克牌随机打乱,并分配给三个人,每人五张牌

算法原码所在位置:

shufflecards · 一直淡水鱼/Java经典例题 - 码云 - 开源中国 (gitee.com)

杨辉三角

题目描述:

代码实现:

java 复制代码
public class Test {
    public static List<List<Integer>> generate(int numRows) {
        List<List<Integer>> list = new LinkedList<>();
        for (int i = 0; i < numRows; i++) {
            List<Integer> row = new LinkedList<>();
            for (int j = 0; j < i + 1; j++) {
                if (j == 0 || i == j) {
                    row.add(1);
                } else {
                    row.add(list.get(i - 1).get(j - 1) + list.get(i - 1).get(j));
                }
            }
            list.add(row);
        }
        return list;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int numRows = scanner.nextInt();
        List<List<Integer>> list = generate(numRows);
        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j < i + 1; j++) {
                System.out.print(list.get(i).get(j) + " ");
            }
            System.out.println();
        }
    }
}

运行结果图:

相关推荐
非优秀程序员42 分钟前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻1 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
文丑颜不良啊3 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang4 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪5 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息5 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼6 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff7 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈
SL_staff7 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc
David猪大卫7 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习