线性表的定义
多个相同类型元素逻辑上连续的有限序列
常见的线性表有:数组(顺序表)、链表、栈、队列、字符串
逻辑连续是指线性表可以在物理上不连续。比如一层宿舍楼,他们是紧挨着的,这种叫物理连续,数组就是一种物理连续。而逻辑连续是在逻辑思维里连续的,在内存空间不一定连续存储。
动态数组的定义
在静态数组的基础上,增加了修改数组长度的功能
实现动态功能
核心:当数组存储满了之后,我们可以利用数组的copyOf方法,将原先数组复制到一个长度为原数组两倍的新数组里,即完成了数组扩容操作,这是动态数组的实现动态的基本要求。
动态数组的增删改查
- 创建一个类,实现数组的初始化,根据自己传入的参数,创建数组
public class MyArrayNote {
//一个整型数组
private int[] data;
//表示数组的有效元素
private int size;
//无参构造,在没有定义长度的时候默认给初值
public MyArrayNote(){
this(10);
}
//初始化数组
public MyArrayNote(int length){
this.data = new int[length];
}
}
- 扩容数组,将原数组复制到两倍长的新数组
public void grow(){
this.data = Arrays.copyOf(data,data.length * 2);
}
- 打印数组,toString()方法
//就自己设计打印一个数组
public String toString(){
String ret = "[";
for (int i = 0; i < size; i++) {
ret += data[i];
if(i != size - 1){
ret += ',';
}
}
ret += ']';
return ret;
}
}
- 在数组的尾部插入元素
public void add(int val){
data[size] = val;
size ++;
if (size == data.length){
grow();
}
}
- 根据传入的索引插入元素
public void addIndex(int index, int val){
//判断边界,可以等于size,就是尾插
if(index < 0 || index > size){
System.out.println("输入错误");
}
//找到索引原来元素,从这个元素开始全部后移,插入新元素
for (int i = size - 1; i >= index ; i--) {
data[i + 1] = data[i];
}
//插入元素
data[index] = val;
size ++;
//判满
if(size == data.length){
grow();
}
}
- 查询第一个值为val的元素下标,返回下标
public int find(int val){
//查找元素
for (int i = 0; i < size; i++) {
if (data[i] == val){
return i;
}
}
return -1;
}
- 查询是否包含这个元素,包含返回true,否则返回false
public boolean contain(int val) {
return find(val) != -1;
}
- 查询当前动态数组中索引为index的元素值
public int findByIndex(int index){
//无法等于size,因为索引为size没有元素
if (index < 0 || index >= size){
System.out.println("输入错误");
return -1;
}
return data[index];
}
- 修改index位置的元素为新值,返回原来的值
public int setByIndex(int index, int newVal){
//判断边界,下标不可以等于size,因为没有这个元素
if(index < 0 || index >= size){
System.out.println("输入错误");
return -1;
}
int oldVal = data[index];
data[index] = newVal;
return oldVal;
}
- 改第一个值为oldval的元素,修改成新的值,并返回是否修改成功
public boolean setByVal(int oldVal, int newVal){
int index = findByIndex(oldVal);
if (index != -1){
data[index] = newVal;
return true;
}
return false;
}
- 删除索引位置的元素,返回删除前的元素值
public int removeByIndex(int index){
if(index < 0 || index >= size){
System.out.println("输入错误");
return -1;
}
int oldVal = data[index];
//覆盖,因为要保证能取到i+1这个元素,所以i要小于size-1
for (int i = index; i < size - 1; i++) {
data[i] = data[i + 1];
}
size --;
return oldVal;
}
- 删除数头的元素
public void removeFir(){
removeByIndex(0);
}
- 删除数尾的元素
public void removeLast(){
removeByIndex(size - 1);
}
- 删除第一个值为val的元素,返回是否删除成功
public boolean removeByVal(int val){
int index = findByIndex(val);
if (index != -1){
removeByIndex(index);
return true;
}
return false;
}
- 删除当前数组中所有值为val的元素
public boolean removeAllVal(int val){
for (int i = 0; i < size; i++) {
//循环判断是否相等并且下标不能越界
while(i < size && data[i] == val){
removeByIndex(i);
return true;
}
}
return false;
}