一、List接口(线性表接口)
1. 线性表
(1)定义:n个具有相同特性的数据元素的有限序列。线性表的逻辑结构是线性结构。
(2)线性表包含:数组,链表,栈,队列,字符串
(3)举个例子:数组
(4)List接口
A. List接口的引出
B. List接口中的常用基本操作方法(CURD)
好处(其实就是多态): 在接口中定义的方法具体的子类中都需要一一实现(覆写),通过不同子类能够调用的方法完全不变(都是上述的方法)
二、动态数组
1. 基本数组特点:保存的单个相同类型的元素。且一旦实例化一个数组,则该数组定长。
2. 由于原始的数组存在定长的问题,因此需要将原始数组封装到自定义的类中,让它具备可扩展的能力,同时将增删改查的基本操作也封装在其中=》即对使用者来说,提供给用户的是一个动态数组,用户无需关心数组的长度问题,只需要使用提供的增删改查基本操作即可。
即为以下的逻辑
3. 定义线性表接口Seqlist
(1)为什么想到用接口:因为多个数据结构都满足线性表的规范
线性表的规范:都是保存单个元素的集合,集合中元素的类型都相同,元素的逻辑结构是连续的
(2)定义接口的好处(多态的好处):降低用户的学习成本和程序员的编写成本。对于用户来说只需要学习接口中的方法即可,对于程序员来说只需要在对应子类中覆写接口中的已有方法即可(也可以在子类中拓展一些方法)。
举例:
A. 没有接口的情况: 如图所示,子类分别定义了增加元素的方法,但是方法名称不同,因此对于用户来说需要学习两个方法
动态数组类的方法:
ArrayList arr = new ArrayList();
arr.addArr(1);
arr.removeArr(1);
链表类
LinkedList list = newLinkedList();
list.add(1);
B. 有接口的情况:如图所示,ArrayList和LinkedList两个子类实现SeqList接口,因此利用多态,只需要在子类中覆写方法即可。用户只需要知道SeqList中的方法即可(当然子类中也可以定义自己独有的方法,不过调用的时候需要向下转型或者直接生成子类对象再去调用)。
SeqList{
//方法是简写的
add(int b );
remove(int a);
...
}
//动态数组
List list = new ArrayList();
list.add;
list.remove;
//链表
List list2 = new LinkedList();
list2.add;
list2.remove;
(3)接口的定义代码
4. 自己实现的动态数组MyArray
(1)定义变量和构造方法
注意:
(2)基本操作的覆写重点讲解(挑了重点部分讲解,明天的总结中有完整代码实现)
A. 注意:size不光记录了线性表中实际有效元素的个数,size作为下标指向的是最后一个有效元素的下一个元素的位置 。如图所示:size = 2表示实际有效元素有两个,且下标为2是最后一个有效元素的下一个元素的位置。
B. 在索引位置添加元素值
a. 在索引位置添加元素值的方法图文解析
b. 代码和测试
注意1:在索引位置插入一个元素的方法中,若在尾插的逻辑后面不return,则在执行完尾插之后,又会插入一个元素。也就是尾插之后size ++ ,导致index比size小一位,for循环将index的位置往后挪动一位,然后将index的位置添加一个元素,相当于插入了两个元素。
C. 注意:删、查、改都是对有效元素的,因此要注意index的范围是在[0,size)之间 因此单独抽象为一个方法,当index合法,则返回true,否则为fals
D. 按照索引删除元素思路
注意1:从前往后依次覆盖
注意2:从前往后开始覆盖,这里的终止条件index + 1 == size - 1也可以,等于size也可以,等于size -1也就是最后一个有效元素没被size的0覆盖,等于size也就是被0覆盖 ,但是由于后面都会size --,因此在访问的时候也访问不到这个位置的元素,也就是所谓的逻辑删除