Java 数据结构—线性表(数组/链表/哈希表/栈/队列)
一、数组(Array)
1. 定义:数组是相同数据类型的元素按一定的顺序排列的集合,具有一致性、有序性和不可变性,是一块连续的内存空间,通过使用索引值来访问元素,是使用最广泛的数据结构;
2. 特点
优点:查询元素快,支持随机访问;
缺点:
A. 新增和删除元素慢;
B. 元素单一且大小固定;
注意:数组是顺序表,在顺序表中间插入或者删除元素需要把该元素之后的所有元素向前或者向后移动;
3. 分类:一维数组和多维数组;
4. 使用场景:如ArrayList底层是使用数组结构实现的。
二、链表(LinkedList)
1. 定义:链表是一种非连续、非顺序的数据结构,数据元素的逻辑顺序是通过链表中的指针连接实现的,链表由一系列结点组成。
2. 特点
优点:新增和删除元素快,空间没有限制,只能顺序访问;
缺点:查询元素慢;
注意:查找元素时需要从头或者尾开始遍历整个链表,直到找到目标元素,在插入或者删除元素时不需要移动元素,只需要改变相关元素的头尾指针即可;
3. 分类
单向链表:一个节点指向下一个节点;
双向链表:一个节点有两个指针域,指针域指向的是另一个节点;
循环链表:能通过任何一个节点找到其他所有的节点;
4. 使用场景:如LinkedList底层是使用双向链表结构实现的。
三、哈希表(Hash Table)
1. 定义:是根据关键码值(Key value)而直接进行访问的数据结构,它通过把关键码值映射到表中一个位置来访问记录,这个映射函数叫散列函数,存放记录的数组叫散列表;
2. hash解决方案
A. Hash冲突;
B. 布谷hash;
C. bloomfilter;
D. hash分散;
E. hash聚集。
四、栈(Stack)
1. 定义:栈是限制线性表中元素的插入(即进栈)和删除(即出栈)只能在线性表的同一端进行的一种特殊线性表。
2. 特点:
A. 栈是一个先进后出(FILO)、后进先出(LIFO)的有序列表,包含进栈(push)和出栈(pop);
B. 栈顶为允许插入和删除的一端,栈底为固定的一端;
C. Stack类是线程安全的,内部使用数组保存数据,不够用时翻倍。
3. 分类
A. 静态栈:使用数组实现的栈;
B. 动态栈:使用链表实现的栈。
4. 应用场景
A. 方法的调用:在调用子程序前,会将下个指令的地址存在堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中;
B. 递归的调用;
C. 二叉树的遍历。
五、队列(Queue)
1. 定义:队列是一种只允许在一端进行插入,另一端进行删除的线性表结构。
2. 特点
A. 队列是先进先出(FIFO)的;
B. 队尾为允许插入(入队)的一端,队头为允许删除(出队)的一端;
3. 分类
按数据结构分:
A. 静态队列:使用数组实现的队列;
B. 动态队列:使用链表实现的队列。
按是否阻塞分:
A. 阻塞队列:包括ConcurrentLinkedQueue(链表线程安全),采用CAS无锁算法的;
B. 非阻塞队列:ArrayBlockingQueue(数组支持的有界)、LinkedBlockingQueue(链表支持的有界)、DelayQueue(调度)、PriorityBlockingQueue(无界优先级),采用ReentrantLock锁机制实现的。
按顺序来分:
A. 单向队列(Queue):只能在一端插入数据,另一端删除数据;
B. 双向队列(Deque):每一端都可以进行插入数据和删除数据操作;
C. 优先级队列(Priority):优先级队列是比栈和队列更专用的数据结构,在优先级队列中,数据项按照关键字进行排序,关键字最小(或者最大)的数据项往往在队列的最前面,而数据项在插入的时候都会插入到合适的位置以确保队列的有序。