线性结构:是一个有序数据元素的集合/是n个具有相同特性的数据元素的有限序列。
除首元素只有“后继”和最后一个元素只有一个“前驱”,其他每个元素只有一个“前驱”元素和一个“后继”元素。
顺序表,链表,栈,队列都属于线性表,线性表在逻辑上是线性结构。线性表在物理上存储时,通常以数组和链式结构的形式存储(栈和队列的实现是由顺序表或链表实现的)
顺序表(ArrayList)是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
ArrayList是用一维数组实现的线性表。
在创建ArrayList时如果不给参数,默认创建的就是一个容量为十的空数组。如果给定一个数组,则设定了数组的初使容量大小。
(Collection<? extends E> c)
Collection是一个接口,List也是一个接口,继承了Collection接口,ArrayList又实现了List接口。(链表LinkedList也实现了List接口)。
所以在创建一个新的ArrayList的时候,可以给一个其他实现了collection接口的对象来获取里面的元素。
List<Integer> mylist1 = new ArrayList<>();
mylist1.add(1);
mylist1.add(2);
mylist1.add(3);
List<Integer> mylist2 = new LinkedList<>(mylist1);
ArrayList默认的是尾插,其他的方法大家可以自己查看。
ArrayList是动态类型的顺序表,在插入元素时会自动扩容。自动扩容会按照1.5倍扩容,如果所需大小超过原空间的1.5倍,按照所需大小扩容。弊端是浪费空间。此外,ArrayList是用数组存放数据的,一旦要在中间插入或删除元素时,就需要将后面的元素整体前移或后移,时间复杂度为O(n),效率比较低。链表则比顺序表更适合做数据的插入删除。但是数组是一段连续的空间,里面元素的大小也相同,在随机访问元素的效率上又高于链表,所以顺序表更适合对固定的数据进行频繁访问。
链表(LinkedList)是一种物理存储上非连续的存储结构,数据元素的逻辑顺序是通过链表种的引用链接次序实现的。也就是前驱和后继
链表的结构也有很多种:
单向或者双向链表。单向就是每一个节点都有一个后继记录下一个结构的地址。双向是每一个节点都有前驱和后继记录前一个节点和后一个节点的地址。
带头或者不带头。带头就是在第一个节点之前还有一个头节点,里面不存储元素,只记录第一个节点的地址。
循环或者非循环。循环是最后一个节点的后继保存了第一个节点的地址。
LinkedList的底层是双向链表结构
链表插入元素也是尾插法。
使用迭代器遍历链表可以正向遍历也可以反向遍历。
栈(stack)
栈遵循先入后出的原则
数据的插入叫做压栈:最先进的1,所以2在1的顶上,3在2的顶上。出栈从栈顶出,此时栈顶是3,3出完出2,2出完出1.
队列(queue)
只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列遵循先进先出原则。插入数据端叫做队尾,删除数据端叫做队头。
入队顺序是1-2-3。出队顺序也是1-2-3。
如果用ArrayList实现队列。出队则需要把队头后面所有的元素前移。如果用LinkedList实现的话只需要修改头节点的位置。