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

运行结果图:

相关推荐
学会沉淀。6 分钟前
Docker学习
java·开发语言·学习
如若1237 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
初晴~37 分钟前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
yuanManGan1 小时前
数据结构漫游记:静态链表的实现(CPP)
数据结构·链表
黑胡子大叔的小屋1 小时前
基于springboot的海洋知识服务平台的设计与实现
java·spring boot·毕业设计
ThisIsClark1 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
雷神乐乐2 小时前
Spring学习(一)——Sping-XML
java·学习·spring
小林coding3 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
V+zmm101343 小时前
基于小程序宿舍报修系统的设计与实现ssm+论文源码调试讲解
java·小程序·毕业设计·mvc·ssm
文大。3 小时前
2024年广西职工职业技能大赛-Spring
java·spring·网络安全