目录
顺序表
初始化
方法实现
1> display 遍历(简单)
2> isFull 是否为满
3> size 顺序表的大小
4> add 增加在最后位置(考虑是否满了) (难)
5> add 增加到指定位置(是否为满)
6> isEmpty 是否为空
7> contain 是否包含某个元素 (简单)
8> indexOf 查找某个位置的元素
9> get 获取 pos 位置的元素
10> set 给 pos 位置的元素设为 value
11> remove 移除某个数据
12> clear 清空顺序表
如何使用
小结
线性表定义:
是 n 个具有相同特性的数据元素的有限序列.线性表示一种在实际中广泛使用的数据结构, 常见的线性表: 顺序表. 链表. 栈. 队列.
线性表在逻辑上是线性结构, 但在物理结构上并不一定是连续的. 线性表在物理上存储时, 通常以数组和链式结构的形式存储
顺序表
顺序表是一个动态扩容的数组.
我们来实现一个顺序表, 需要通过这个数组写一些方法实现各种功能.
初始化
先来给顺序表创建一个数组.
public static final int DEFAULT_SIZE = 10;public int[] elem;public int usedSize = 0;public MyArrayList() {this.elem = new int[DEFAULT_SIZE];}
分配一个数组, usedSize 表示这个数组初始时里面0个数据, DEFAULT_SIZE 表示数组默认大小为10.我们也可以自己创建顺序表时来指定数组的默认大小, 通过构造函数传参来实现.
public MyArrayList(int size) {this.elem = new int[size];}
方法实现
如何实现各种功能, 先来实现一个接口, 通过这个接口来说明我们想要实现的功能:
package myList;public interface IList {// 新增元素,默认在数组最后新增public void add(int data);// 在 pos 位置新增元素public void add(int pos, int data);// 判定是否包含某个元素public boolean contains(int toFind);// 查找某个元素对应的位置public int indexOf(int toFind);// 获取 pos 位置的元素public int get(int pos);// 给 pos 位置的元素设为 valuepublic void set(int pos, int value);//删除第一次出现的关键字keypublic void remove(int toRemove);// 获取顺序表长度public int size();// 清空顺序表public void clear();// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的public void display();// 判断是否为满public boolean isFull();// 判断是否为空public boolean isEmpty();
}
然后写一个类来实现其中的代码:
package myList;public class MyArrayList implements IList{public static final int DEFAULT_SIZE = 10;public int[] elem;public int usedSize = 0;public MyArrayList() {this.elem = new int[DEFAULT_SIZE];}public MyArrayList(int size) {this.elem = new int[size];}@Overridepublic void add(int data) {}@Overridepublic void add(int pos, int data) {}@Overridepublic boolean contains(int toFind) {return false;}@Overridepublic int indexOf(int toFind) {return 0;}@Overridepublic int get(int pos) {return 0;}@Overridepublic void set(int pos, int value) {}@Overridepublic void remove(int toRemove) {}@Overridepublic int size() {return 0;}@Overridepublic void clear() {}@Overridepublic void display() {}@Overridepublic boolean isFull() {return false;}@Overridepublic boolean isEmpty() {return false;}
}
1> display 遍历(简单)
@Overridepublic void display() {for(int i = 0; i < this.usedSize; i++) {System.out.println(this.elem[i]+ " ");}System.out.println();}
2> isFull 是否为满
@Overridepublic boolean isFull() {return this.usedSize == elem.length;}
3> size 顺序表的大小
@Overridepublic int size() {return this.usedSize;}
4> add 增加在最后位置(考虑是否满了) (难)
注意: 满了就扩容: 怎么扩容? 使用 copyOf 方法.
@Overridepublic void add(int data) {if(isFull()) {elem = Arrays.copyOf(elem, 2*elem.length);}this.elem[this.usedSize] = data;usedSize++;}
5> add 增加到指定位置(是否为满)
注意: 看放的位置是否合法, 不能是负数或者太靠后不连贯了.
解决方法: 写一个方法来检查位置是否合法, 不合法的话抛出异常
此处的异常是自定义异常
package myList;public class PosIllegality extends Exception {public PosIllegality(String msg) {super(msg);}
}
private void checkPosOnAdd(int pos) throws PosIllegality {if(pos < 0 || pos > usedSize) {System.out.println("位置不合法");throw new PosIllegality("插入元素下标异常: " + pos);}}
代码实现:
@Overridepublic void add(int pos, int data) {try {checkPosOnAdd(pos);}catch (PosIllegality e) {e.printStackTrace();return;}if(isFull()) {elem = Arrays.copyOf(elem, 2*elem.length);}for (int i = usedSize-1; i >= pos; i--) {elem[i+1] = elem[i];}elem[pos] = data;usedSize++;}
步骤:
1> 检查位置合法性
2> 检查是否数组满了
3> 开始进行位移: 从最后一个有效的数据开始往后移动, 当i< pos 时结束, 存放元素到 pos位置, usedSize++
6> isEmpty 是否为空
@Overridepublic boolean isEmpty() {return this.usedSize == 0;}
7> contain 是否包含某个元素 (简单)
注意: 看是否为空
@Overridepublic boolean contains(int toFind) {if(isEmpty()) {return false;}for(int i = 0; i < this.usedSize; i++) {if(toFind == elem[i]) {return true;}}return false;}
8> indexOf 查找某个位置的元素
注意: 看是否为空
@Overridepublic int indexOf(int toFind) {if(isEmpty()) {return -1;}for(int i = 0; i < this.usedSize; i++) {if(toFind == elem[i]) {return i;}}return -1;}
9> get 获取 pos 位置的元素
注意: 判断位置是否合法, 其中的异常是自定义异常
package myList;public class MyArrayListEmpty extends Exception {public MyArrayListEmpty(String msg) {super(msg);}
}
package myList;public class PosIllegality extends Exception {public PosIllegality(String msg) {super(msg);}
}
@Overridepublic int get(int pos) throws MyArrayListEmpty {try {checkPosOnGet(pos);}catch (PosIllegality e) {e.printStackTrace();return -1;}if(isEmpty()) {throw new MyArrayListEmpty("获取指定下标元素时, 顺序表为空!");}return elem[pos];}private void checkPosOnGet(int pos) throws PosIllegality {if(pos < 0 || pos > usedSize) {System.out.println("不合法");throw new PosIllegality("获取指定下标的元素异常: " + pos);}}
10> set 给 pos 位置的元素设为 value
注意: pos 位置是否合法
package myList;public class PosIllegality extends Exception {public PosIllegality(String msg) {super(msg);}
}
@Overridepublic void set(int pos, int value) {try {checkPosOnSet(pos);} catch (PosIllegality e) {throw new RuntimeException(e);}elem[pos] = value;}private void checkPosOnSet(int pos) throws PosIllegality {if(pos < 0 || pos > usedSize) {System.out.println("不合法");throw new PosIllegality("获取指定下标的元素异常: " + pos);}}
11> remove 移除某个数据
注意: 看是否有这个数据.没有的话可以抛出异常.有的话就依次覆盖前一个数据
@Overridepublic void remove(int toRemove) {int index = indexOf(toRemove);if(index == -1) {System.out.println("没有找到这个数字!");return ;}for(int i = index; i < this.usedSize-1; i++) {elem[i] = elem[i+1];}usedSize--;}
12> clear 清空顺序表
最简单的一种方式
@Overridepublic void clear() {this.usedSize = 0;}
当里面的数据时引用数据类型时需要释放内存
@Overridepublic void clear() {for (int i = 0; i < usedSize; i++) {elem[i] = null;}this.usedSize = 0;}
如何使用
可以通过 main 函数调用这个类中方法
package myList;/*** 类的使用者*/
public class Test {public static void main(String[] args) {MyArrayList myArrayList = new MyArrayList();myArrayList.display();}
}
小结
当添加元素或者删除元素时 注意: usedSize++ 或者 usedSize--
加入和删除 注意实现的过程.
注意下标不合法等异常