当前位置: 首页 > news >正文

【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 类型的顺序表:

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);//指定顺序表初始容量

 代码示例:

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常见操作

尾插

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

将元素插入到指定位置

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

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

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

删除指定位置元素

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

删除指定数据

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

获取指定位置元素

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

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

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

清空顺序表

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

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

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

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

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

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

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

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增强循环、使用迭代器

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)

杨辉三角

题目描述:

代码实现:

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

 运行结果图:

http://www.lryc.cn/news/397879.html

相关文章:

  • 对接高德开放平台API
  • Linux 初识
  • CSS技巧专栏:一日一例 4.纯CSS实现两款流光溢彩的酷炫按钮特效
  • int类型变量表示范围的计算原理
  • STM32崩溃问题排查
  • CSS 【详解】样式选择器(含ID、类、标签、通配、属性、伪类、伪元素、Content属性、子代、后代、兄弟、相邻兄弟、交集、并集等选择器)
  • CMakeLists.txt编写思路
  • 红日靶场----(三)2.漏洞利用
  • LeetCode HOT100(三)滑动窗口
  • 数学系C++ 排序算法简述(八)
  • 记一下blender曲线阵列
  • Windows电脑安装Python结合内网穿透轻松搭建可公网访问私有网盘
  • react hooks antd 父组件取子组件form表单的值
  • 【ARMv8/v9 GIC 系列 1.7 -- GIC PPI | SPI | SGI | LPI 中断使能配置概述】
  • 大数据如何推动工业数字化发展?
  • 计算机网络浅谈—什么是 OSI 模型?
  • 浪潮服务器内存物理插槽位置
  • windows node降级到指定版本
  • EXSI 实用指南 2024 -编译环境 Mac OS 安装篇(一)
  • 断电的固态硬盘数据能放多久?
  • Neo4j安装
  • 基于Java+SpringMvc+Vue技术的就医管理系统设计与实现系统(源码+LW+部署讲解)
  • Transformer学习过程中常见的问题与解决方案 - Transformer教程
  • Linux进程间通信:匿名管道 命名管道
  • 【数据结构】(C语言):二叉搜索树(不使用递归)
  • Fastapi在docekr中进行部署之后,uvicorn占用的CPU非常高
  • Pandas数据可视化宝典:解锁图形绘制与样式自定义的奥秘
  • 2024前端面试真题【JS篇】
  • axios使用sm2加密数据后请求参数多了双引号解决方法
  • MybatisPlus 核心功能