朝暮与年岁共往,然后与你一同行至天光
大家好,这里是新一,请多关照🙈🙉🙊。在本篇博客中,新一将带大家正式进入数据结构的学习,顺序表的增删查改,干货满满哟。(以下结果均在IDEA中编译)希望在方便自己复习的同时也能帮助到大家。😜😜😜🥇🥈🥉
废话不多说,直接进入我们的文章。
一.🥇 概念与结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
静态顺序表:使用定长数组存储。
动态顺序表:使用动态开辟的数组存储。
静态顺序表适用于确定知道需要存多少数据的场景.静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用.相比之下动态顺序表更灵活, 根据需要动态的分配空间大小.
二.🥇 接口实现
我们先来实现一个顺序表,包含增删查改等各接口
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created with IntelliJ IDEA.
* Description:顺序表
* User: mac
* Date: 2022-08-30
* Time: 20:41
*/
public class MyArrayList {
public int[] elem;
public int usedSize;//有效数据个数
public MyArrayList() {
this.elem = new int[2];//要先在构造函数中声明顺序表初始长度
}
//打印顺序表
public void display() {
for (int i = 0; i < this.usedSize; i++) {
System.out.print(this.elem[i] + " ");
}
System.out.println();
}
//获取顺序表有效数据长度
public int size() {
return this.usedSize;
}
//在pos位置新增元素
public void add(int pos, int data) {
if (pos < 0 || pos > this.usedSize){//新增元素需要判断pos位置是否合法
System.out.println("pos位置不合法");
return;
}
if (isFull()){//还要判断顺序表是否满
this.elem = Arrays.copyOf(this.elem, this.elem.length * 2);//copyof扩容
System.out.println("空间不足已扩容成功");
}
for (int i = this.usedSize - 1; i >= pos; i--) {
this.elem[i + 1] = this.elem[i];
}
this.elem[pos] = data;
this.usedSize++;
}
//判断满
public boolean isFull() {
return this.usedSize == this.elem.length;
}
//判断是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if (this.elem[i] == toFind) {
return true;
}
}
return false;
}
//查找某个元素对应的位置
public int search(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if (this.elem[i] == toFind) {
return i;
}
}
return -1;
}
//获取pos位置的值
public int getPos(int pos) {
if (pos < 0 || pos >= this.usedSize) {
System.out.println("pos位置不合法");
return -1;//业务上的处理不考虑这些,可以抛异常解决 - 后续博客说明
}
if (isEmpty()) {
System.out.println("顺序表为空!");
return -1;
}
return this.elem[pos];
}
//判空
public boolean isEmpty() {
return this.usedSize == 0;
}
//给pos位置的元素设置为value
public void setPos(int pos, int value) {
if (pos < 0 || pos >= this.usedSize){
System.out.println("pos位置不合法");
return;
}
if (isEmpty()){
System.out.println("顺序表为空");
return;
}
this.elem[pos] = value;
}
//删除第一次出现的关键字
public void remove(int toRemove) {
if (isEmpty()) {
System.out.println("顺序表为空!");
return;
}
int index = search(toRemove);
if (index == -1){
System.out.println("没有要删除的数字");
return;
}
for (int i = index; i < this.usedSize - 1; i++) {
this.elem[i] = this.elem[i + 1];
}
this.usedSize--;
//this.elem[usedSize] = null;如果数组当中是引用数据类型
}
//清空顺序表
public void clear() {
this.usedSize = 0;
//如果为引用类型
/*for (int i = 0; i < usedSize; i++) {
this.elem[i] = null;
}*/
}
}
各位可以参考我的代码在IDEA环境下试试🧐🧐🧐
三.🥇 顺序表的问题与思考
- 顺序表中间/头部的插入删除,时间复杂度为O(N)
- 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
- 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
那么我们该怎么解决呢?链表
关于链表我们在下一篇博客中说明
想对大家说的话
家人们,学到这里我们已经了解了顺序表的增删查改🥳🥳🥳,后续新一会持续更新JAVA数据结构的有关内容,学习永无止境,技术宅,拯救世界!