目录
1. 线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的。线性表在物理上存储时(存储在内存时),通常以数组和链式结构的形式存储。
2. 顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分:
1. 静态顺序表:使用定长数组存储。
2. 动态顺序表:使用动态开辟的数组存储。
2.1 动态数组
动态数组,就是在普通数组上增加了一个可以根据元素的个数动态调整数组大小的功能。
Java中提供的数组都是静态数组 int[] char[] long[] (定义之后没法改变长度),需要我们自己定义一个类,拓展基础数组的功能。
class MyArray { // 存放元素仍然还是int[] // data数组的长度,让用户来指定 private int[] date; // 表示当前动态数组中已经存储的元素个数 private int size; }
定义 size 成员属性,size 这个属性永远是当前有效元素的下一个位置的索引。下一次再存储新的元素时候,直接使用 size 对应的索引即可。
toString 用字符串格式化输出数组
/** * toString 用字符串格式化输出数组 */ public String toString() { String ret = "["; // 此时取得是有效数据,使用size属性 // size表示当前有效元素的下一个索引位置 for (int i = 0; i < size; i++) { ret += date[i]; if (i != size - 1) { ret += ", "; } } ret += "]"; return ret; }
2.2 增删查改
增
public void add (int val):向当前动态数组中添加元素——>添加到数组末尾
/** * 在当前数组中添加一个新的元素 */ public void add(int val) { date[size] = val; size++; //元素在添加的过程中可能把当前数组占满 if (size == date.length) { //此时数组已满,需要扩容 grow(); } } /** * 对于外部的使用者来说,不知道 MyArray 这个类中还有个int[], * 数组的扩容对外部也是不可见的 * 故设置为private权限 */ private void grow() { //copyOf方法返回扩展后的新数组 this.date = Arrays.copyOf(date, 2 * date.length); }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] } } //输出结果 [10,20,30,40]
public void addIndex (int index,int val):向当前动态数组中 index 索引位置添加一个新的元素
/** * 增加一个元素 value 到 index 位置 * 重点!!! */ public void add(int index, int va) { //1.先判断边界条件,index 是否非法 //size是有效数组元素 //2.index==size,就是在数组尾部插入 //index==0,就是在头部插入 if (index < 0 || index > size) { System.err.println("add index illegal!"); return; } //从最后一个有效元素开始向后搬移,把index位置空出来 for (int i = size - 1; i >= index; i--) { date[i + 1] = date[i]; } //空出的index位置,插入添加值 date[index] = val; size++; //判断数组是否已满,满则扩容 if (size == date.length) { grow(); } } private void grow() { //copyOf方法返回扩展后的新数组 this.date = Arrays.copyOf(date, 2 * date.length); }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] myArray.add(0,0);//[0,10,20,30,40] myArray.add(2,50);//[0,10,20,50,30,40] myArray.add(6,100);//[0,10,20,50,30,40,100] System.out.println(myArray); } } //输出结果 [0, 10, 20, 50, 30, 40, 100]
查
public int getByValue(int val):查询当前动态数组中第一个值为val的元素索引
/** * 查询当前动态数组中第一个值为val的元素对应的索引 * 若不存在,返回 -1,表示当前val不存在 */ public int getByValue(int val) { for (int i = 0; i < size; i++) { if (date[i] == val) { return i; } } // 还没找到val,不存在 return -1; }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.getByValue(10));//0 } } //输出结果 0
public boolean contains(int val):查询当前动态数组中是否包含值为 val 的元素,若存在返回true,否则返回false
/** *判断当前动态数组中是否包含值为val的元素 */ public boolean contains(int val) { return getByValue(val) != -1; }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.contains(20));//true System.out.println(myArray.contains(100));//false } } //输出结果 true false
public int get(int index):查询当前动态数组中索引为 index 的元素值
/** * 查询当前动态数组中索引为index的元素值 */ public int get(int index) { //1.判断index的合法性 //size有效元素的下一个位置 if (index < 0 || index >= size) { System.err.println("get index illegal!"); return -1; } return date[index]; }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.get(3));//40 } } //输出结果 40
改
public int set(int index,int newVal):修改 index 位置的元素为新的值 newVal ,返回修改前的值
/** * 修改当前动态数组中索引为index位置的元素值为newVal,返回修改前的值 */ public int set(int index, int newVal) { //判断合法性 if (index < 0 || index >= size) { System.err.println("set index illegal"); return -1; } int oldVal = date[index]; date[index] = newVal; return oldVal; }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.set(1,200));//20 System.out.println(myArray);//[10,200,30,40] } } //输出结果 20 [10, 200, 30, 40]
public boolean setValue(int oldVal, int newVal):修改第一个值为 oldVal 的元素,更改为新的值newVal,返回是否修改成功
/** * 将动态数组中第一个值为 oldVal 的元素修改为 newVal */ public boolean setValue(int oldVal, int newVal) { int index = getByValue(oldVal); //判断合法性 if (index != -1) { date[index] = newVal; return true; } System.out.println("oldVal is not exist!"); return false; }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.setValue(10,100));//true System.out.println(myArray); System.out.println(myArray.setValue(50,500));//false } } //输出结果 true [100, 20, 30, 40] oldVal is not exist! false
删
public int remove(int index):删除索引为index对应的元素,返回删除前的元素值
/** * 删除索引为 index 对应的元素,返回删除前的元素值 */ public int remove(int index) { //判断合法性 if (index < 0 || index >= size) { System.err.println("remove index illegal"); return -1; } int oldVal = date[index]; //元素搬移,从index开始,后一个元素覆盖前一个元素,一直走到size - 1(最后一个有效元素) // data[i] = data[i + 1] //最后一个元素向前搬移 i+1 == size - 1 ——> i < size - 1 for (int i = index; i < size - 1; i++) {//i < size -1 防止访问无效元素 date[i] = date[i + 1]; } size--; return oldVal; }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.remove(1)); System.out.println(myArray); } } //输出结果 20 [10, 30, 40]
public int removeFirst():删除数组的头元素
/** * 删除第一个的元素,返回删除前的元素值 */ public int removeFirst() { return remove(0); }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.removeFirst()); System.out.println(myArray); } } //输出结果 10 [20, 30, 40]
public int removeLast():删除数组的尾元素
/** * 删除最后一个元素,返回删除前的元素值 */ public int removeLast() { return remove(size - 1); }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.removeLast()); System.out.println(myArray); } } //输出结果 40 [10, 20, 30]
public boolean removeByValueOnce(int val):删除第一个值为val的元素,返回是否删除成功
/** *删除当前动态数组中第一个值为val的元素,返回是否删除成功 */ public boolean removeByValueOnce(int val) { for (int i = 0; i < size; i++) { if (date[i] == val) { remove(i); return true; } } return false; }
测试
public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(3); myArray.add(10); myArray.add(20); myArray.add(30); myArray.add(40); //[10,20,30,40] System.out.println(myArray.removeByValueOnce(20)); System.out.println(myArray); } } //输出结果 true [10, 30, 40]