顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般采用数组存储。
所以我们对顺序表进行操作时,可理解为就是对一个数组进行操作。
操作时需要时刻注意以下三个点:
- 1、顺序表是否满了
- 2、所操作位置是否合法
- 3、插入数据时,所插入位置前一定要有数据
public class MyArrayList{ //自己定义一个顺序表的类,实现该顺序表下的各种功能
private int[] elem;
private int useSize;
public MyArrayList(){ //无参构造方法,初始给出顺序表的默认大小
this.elem = new int[10];
}
public MyArrayList(int capacity){
this.elem = new int[capacity];
}
//接下来我们实现顺序表中的各种功能
// 一、打印顺序表
// 我们需要遍历顺序表中的每个元素,就和打印数组的方法一样
public void display(){
for(i = 0; i < this.useSize; i++){
System.out.print(this.elem[i] + " ")
}
System.out.println();
}
// 二、在pos位置新增元素 —— 似乎顺序表并不能使用插入操作,只能依次放入元素
// 我们要在给定pos位置插入元素,需要有两个前提:
// 1、判断顺序表是否已经满了(写一个判断是否顺序表满了的函数)
public boolean isFull(){
if(this.useSize == this.elem.length){
return true;
}
return false;
}
// 如果顺序表满了,则需要扩充,写一个扩充顺序表的函数
public void expansion(){
this.elem = Arrays.copyOf(this.elem, 2*this.elem.length); //使用此函数可以将顺序表大小变为原来的两倍
// ArraycopyOs(原始数组, 复制后新数组的长度),其返回的是一个复制后的新数组,此处将新数组的地址赋于this.elem
}
// 2、判断给定pos位置是否合理
public void add(int pos, int data){
if(isFull == true){
//顺序表已满,需要扩充
expansion();
return;
}
if(pos < 0 || pos > this.useSize){
System.out.println("pos位置不合法");
return;
}
this.elem[pos] = data;
this.useSize++;
// 我们直接将新元素放在顺序表的末尾
public void addLast(int data){
if(isFull == true){
expansion();
return;
}
this.elem[useSize] = data;
this.useSize++;
}
// 三、判断是否包含某个元素
public boolean contains(int toFind){
for(i = 0; i < this.useSize; i++){
if(this.elem[i] == toFind){
return true;
}
}
return false;
}
// 四、查找某个元素对应的位置
public int search(int toFind){
for(i = 0; i < this.useSize; i++){
if(this.elem[i] == toFind){
return i;
}
}
return -1;
}
// 五、获取pos位置的元素
public int gerPos(int pos){
if(pos < 0 || pos >= this.useSize){
System.out.println("pos位置不合法")
return -1;
}
int ret = this.elem[pos];
return ret;
}
// 六、将pos位置的元素修改为value
public void setPos(int pos, int value){
if(pos < 0 || pos >= this.useSize){
return;
}
this.elem[pos] = value;
}
// 七、删除第一次出现的关键字key
public void remove(int toRemove){
// 搜索该数组中是否由目标关键字,返回其下标
int index = search(toRemove);
if(intdex == -1){
System.out.println("没有目标关键字")
return;
}
// 为了删除当前关键字,则将该关键字后面的每个元素都向前移动一位
for(i = index; i < this.useSize; i++){
this.elem[i] = this.elem[i+1];
}
this.useSize--;
}
// 八、获取顺序表长度
public int size(){
return this.useSize;
}
// 九、清空顺序表
public void clearn(){
this.useSize = 0;
}
}
有关顺序表的一些优缺点:
- 1、顺序表中间/头部的插入删除,时间复杂度为O(N)
- 2、增容需要申请新空间,拷贝数据,释放旧空间,会有不少消耗
- 3、如果通过下标直接取数据,时间复杂度可达到O(N)