【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();
        }
    }
}

运行结果图:

相关推荐
架构文摘JGWZ35 分钟前
Java 23 的12 个新特性!!
java·开发语言·学习
CV工程师小林36 分钟前
【算法】BFS 系列之边权为 1 的最短路问题
数据结构·c++·算法·leetcode·宽度优先
Navigator_Z1 小时前
数据结构C //线性表(链表)ADT结构及相关函数
c语言·数据结构·算法·链表
还听珊瑚海吗1 小时前
数据结构—栈和队列
数据结构
Aic山鱼1 小时前
【如何高效学习数据结构:构建编程的坚实基石】
数据结构·学习·算法
拾光师2 小时前
spring获取当前request
java·后端·spring
aPurpleBerry2 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j
我是苏苏2 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
xujinwei_gingko2 小时前
Spring IOC容器Bean对象管理-Java Config方式
java·spring
2301_789985942 小时前
Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
java·开发语言·学习