前言
顺序表,顾名思义,其实就是一个数组,一块连续的内存,是学习数据结构的入门,那我们可以实现什么操作呢?且听我娓娓道来~
顺序表的基本功能
我定义了一个接口,这里面便是顺序表的基本功能-》
public interface IList {
void add(int data) ;
// 在 pos 位置新增元素
void add(int pos, int data) ;
// 判定是否包含某个元素
boolean contains(int toFind);
// 查找某个元素对应的位置
int indexOf(int toFind);
// 获取 pos 位置的元素
int get(int pos);
// 给 pos 位置的元素设为 value
void set(int pos, int value);
//删除第一次出现的关键字key
void remove(int toRemove);
// 获取顺序表长度
int size();
// 清空顺序表
void clear() ;
// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
void display();
}
具体实现
1.初始化
定义了一个长度为6的数组,数据结构的学习少不了画图哦!,所以很多东西有时候画画图就理解了
public class MyArrayList implements IList
{
public int[] elem;
int usedSize;//记录数组的元素个数
public MyArrayList(){
this.elem=new int[6];//定义数组长度为6
}
2.增删查改的实现
2.1 add增的实现
在添加的过程中,在末尾添加,则是要考虑数组是否是满的情况,如果满了,就要扩容
public void add(int data) {
if (isFull()) {//满了就扩容
kuoRong();
}
elem[useSize++] = data;
}
private void kuoRong(){//判断是否要扩容
elem = Arrays.copyOf(elem, elem.length * 2);
}
private boolean isFull() {//判断顺序表是否满
return useSize==elem.length;
}
那如果要在指定位置pos插入元素呢?如下图,pos后面的元素都要往后移动一格,给其让位置,这时往后遍历就很方便,同时usedSize加1;但是也别忘了特殊情况,要判断数组是否满以及插入的位置是否合法
public void add(int pos, int data) {
if(!checkPosInAdd(pos)){
System.out.println("pos位置不合法!");
return;
}
if(isFull()){
kuoRong();
}
//移动元素
for (int i = useSize-1; i >pos ; i--) {
elem[i+1]=elem[i];}
//插入元素
elem[pos]=data;
usedSize++;
}
// 检查插入位置是否合法
private boolean checkPosInAdd(int pos) {
return pos >= 0 && pos <= useSize;
}// 位置必须在当前元素范围内
2.2 remove删的实现
删除首先检查要删的元素在不在,要是在就获取其下标,循环遍历,把后面的元素全部往前移动一格,同时usedSize-1,
public void remove(int toRemove) {
//第一步检查要删除的关键字是否存在
int pos=indexOf(toRemove);
if(pos==-1){
System.out.println("删除位置不合法!");
return;
}
for (int i = pos; i <usedSize-1 ; i++) {
elem[i]=elem[i+1];
}
usedSize--;
}
那如果要删除全部的指定元素呢?毕竟数组可能有多个一样的元素,便可以采用双指针法,这和一般的去重是一样的道理,只要不是要删的元素,就将该元素移动到数组[count]所在位置。
@Override
// 删除所有指定数字
public void removeAll(int toRemove) {
int count = 0; // 计数器,记录不等于指定数字的元素个数
// 遍历数组
for (int i = 0; i < useSize; i++) {
// 当元素不等于指定数字时,将其移动到计数器所在位置,并增加计数器的值
if (elem[i] != toRemove) {
elem[count++] = elem[i];
}
}
useSize = count; // 更新数组大小为计数器的值
}
2.3 find查的实现
查的实现之前在数组的学习中接触过了,道理是一样,不过也是要考虑其可行性!
@Override
public int indexOf(int toFind) {//返回寻找元素的下标
for (int i = 0; i <elem.length ; i++) {
if(elem[i]==toFind){
return i;
}
} return -1;
}
@Override
public int get(int pos) { // 获取 pos 位置的元素
if(!checkPosInAdd(pos)){
System.out.println("get的pos位置不合法!");
}
return elem[pos];
}
public boolean contains(int toFind) {//是否包含要寻找的元素
for (int i = 0; i <elem.length ; i++) {
if(elem[i]==toFind){
return true;
}
}
return false;
}
2.4 set改的实现
对于顺序表中数据的修改,也是要考虑修改的位置是否合法
// 给 pos 位置的元素设为 value
public void set(int pos, int value) {
if(!checkPosInAdd(pos)){
System.out.println("pos位置不合法!");
}
elem[pos]=value;
}
3.基本功能的实现
打印顺序表
// 打印的第一种方式
public void display() {
for (int i = 0; i < this.elem.length; i++) {
System.out.print(this.elem[i] + " ");
}
System.out.println();
}
// 打印的第二种方式,用Arrays.toString直接打印
public void display() {
System.out.println(Arrays.toString(this.elem));
}
获取顺序表的有效长度
public int size() {
return useSize;
}
清空顺序表
public void clear() {
//万一是引用数据类型
/*for (int i = 0; i < useSize; i++) {
elem[i] = null; // 将每个元素设为null释放引用
}*/
useSize = 0;//一般直接置0
}
😄好了,今天的文章就分享到这里了,希望对你有所收获,下篇见😁