堆、栈、队列、链表
数据结构中的堆栈和内存中的堆栈不是一回事的。
堆
堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:
-
堆中某个节点的值总是不大于或不小于其父节点的值;
-
堆总是一棵完全二叉树。
堆是非线性数据结构,相当于一维数组,有两个直接后继
堆是一种经过排序的树形数据结构,每个节点都有一个值。通常我们所说的堆的数据结构是指二叉树。堆的特点是根节点的值最小(或最大),且根节点的两个树也是一个堆。由于堆的这个特性,常用来实现优先队列,堆的存取是随意的,这就如同我们在图书馆的书架上取书,虽然书的摆放是有顺序的,但是我们想取任意一本时不必像栈一样,先取出前面所有的书,书架这种机制不同于箱子,我们可以直接取出我们想要的书。
它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。
栈
类似于垃圾桶的存储数据的结构。是一种连续存储的数据结构,特点是存储的数据先进后出。利用两个栈可以实现前进后退这种功能。
栈的应用场景
windows系统进入到D://adir/bdir/cdir 退出操作就用到了栈。
依次将目录地址按照a、b、c入栈,入栈完毕此时栈顶指针指向的是c。
出站时c、b、a出栈。一个栈的中资源出栈时,将此资源入栈到另一个栈;一个栈的资源入栈时将另一个栈中的资源出栈。
每次资源调度器都是调用的两个栈的栈顶指向的目录,从而实现返回的功能操作。
常用的实现类:LinkedList
API:
void push(E e) //入栈
E pop() //出栈
队列Queue
类似于没底的垃圾桶。每次只能从队首取元素,从队尾加元素。队列可以保存一组元素,但是存取元素必须遵行先进先出、后进后出。
java.util.Queue接口
Queue是队列,其继承自Collection。即也有集合中的方法。
常用的实现类:LinkedList
它除了实现了List接口之外,也实现了Queue接口。
API:
boolean offer(E e) //入队列操作,每次将给定的元素追加到队列末尾。内部实现相当于add( )方法,之所以这么写相当于一种规范。
E poll() //出队操作。每次调用将队首的元素删除,返回值为被删除的元素。
E peek() //引用队首元素。不会删除队首元素,每次只将队首元素返回。
由于队列也是集合,所以可以使用迭代器遍历。并且这种遍历不会影响队列中的元素。
双端队列
java.util.Deque接口
Deque接口继承了Queue的接口。Deque双端队列,即两端都可以入队出队。
API:
boolean offerFirst(E e) //从队列首入队列
boolean offerLast(E e) //从队列尾入队列
E pollFirst() //从队列首出队列,并删除该元素
E pollLast() //从队列尾出队列,并删除该元素
双端队列可以通过offerFirst,pollFirst即队首入队首出实现栈。
BlockingQueue、BlockingDeque
BlockingQueue阻塞单项队列,它是实现了Collection接口的一个子接口。里面规定了线程安全队列的方法。
BlockingDeque阻塞双端队列,它是实现了BlockingQueue、Deque的一个子接口。
阻塞队列是并发安全的队列,采用双缓冲,在并发安全的前提下解决互斥问题效率更高。
Collections提供了将现有的集合转换为并发安全的集合。一个并发安全的集合不和迭代器互斥,这意味着并发同时做迭代操作和添加删除元素等操作时,会出现并发安全问题。
在多线程下使用队列和栈的时候用LinkedLiset是不行的,因为LinedList不是线程安全的。
BlockingQueue接口:
也称双缓冲队列,在多线程并发时若需要使用队列,我们可以使用Queue然后对做同步操作,但是这样会降低并发对Queue操作的效率。
而BlockingQueue内部使用两条队列分别用来取元素和放元素,即可允许两个线程同时向队列一个做存储,一个做取出的操作。这样就可以既安全效率又高。
它经常使用的实现类有:
ArrayBlockingQueue:是定长的队列,即在实例化对象的时候需要我们指定队列的长度。
LinkedBlockingQueue:最常用的的。动态分配队列长度的队列。实际上还是有长度的即int的最大值,因为任何队列都是由size的且返回的是一个int值,所以size最大值就是int的最大值。
构造器:
BlockingQueue<T> queue = new LinkedBlockingQueue<T>(int size) //参数为队列的长度。
offer() //重载的offer方法,当给的元素个数超过设定的队列长度时。阻塞等待给定的时间后在添加我们给定的元素。 参数为添加的元素,等待多久时间,时间的单位。
PriorityBlockingQueue:要求放的时候给一个比较器,按照比较器排序的方式进行自然排序
SynchronousQueue:特殊的BlockingQueue,存取元素必须是交替调用,即不能连续存或连续取。