1.数组
数组应该是数据结构里面最简单的数据结构了。数组是不可变的。在创建数组的时候就必须指定数组的大小。
初始化数组的三种方式
int[] temp = new int[5];
int[] temp1= {14,5,6};
int[] temp2= new int[]{1,2,3,4,5,6,7,22};
java里面的ArrayList和Vector底层就是以数组形式实现的。两者的区别是Arraylist是线程不安全的,但是Vector是线程安全的(主要是通过在方法上加synchronize关键字实现的线程安全)。
图例
数组最大的优点就是访问速度快,因为每个元素有唯一的索引,可以根据索引快速定位到索引所在位置的元素。
但是缺点就是在进行删除操作的时候。加入我们要把上面的元素3删除,那么我们需要把3后面的所有元素都向前挪动一个位置,如果数组长的话那么对效率有很大影响。
2.链表
链表分为单向链表和双向链表两种,两者的区别就是一个是单向遍历,当前节点只存储自己的下一个节点。一个是可以双向遍历,当前节点即存储了自己的上一个节点,也存储自己的下一个节点。
下图分别是单向链表和双向链表
可以看出来链表在遍历的情况下会很慢,因为他必须是一个一个节点来进行遍历查找的(如果是获取第一个或者最后一个节点跟数组效率相同,因为一般的链表结构都会存储第一个和最后一个节点)。但是才进行更新或者删除的时候效率要好于数组,因为他不需要对后面的数据进行改动,他只需要把需要修改的节点的上一个节点和上一个节点进行适当的修改就可以,其他的节点不需要做任何改动。
单向链表适合于单方向遍历,双向链表适合于双方向遍历。java里面的LinkedList就是一个双向链表。
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
3.栈
栈的数据结构是先入后出(FILO)的,下面是图例。
栈有主要的三个方法
1.pop 栈顶的数据弹出并删除栈顶的数据,栈顶变为下一个元素。
2.peek 只把栈顶的数据弹出 ,但是栈顶不变。
3.push 把一个数据压入栈顶,栈顶发生变化。
java里面的Stack类就是实现的栈的数据结构,大家有兴趣可以去看一下源码,它的底层也是通过数组来进行实现的。
4.队列
队列的数据结构跟栈的结构相似,但是栈的数据结构是先入后出,但是队列的数据结构是先入先出(FIFO)的数据结构。
队列插入的时候只可以从队列尾部插入,获取数据的时候需要从头部获取。
队列分为单向队列和双向队列,对应java里面就是以queue结尾的队列是单向队列,以deque结尾的队列为双向队列。
队列的底层实现就是通过链表的数据结构来实现的,比如单向队列就是带有删除功能的单向链表。这个大家有兴趣可以去看一下LinkedBlockingQueue的源码来看一下。
队列的常用方法
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞