相关数据结构
数据存储的常用结构有:栈
队列
数组
链表
红黑树
栈
栈的特点
先进后出(FILO)
或者 后进先出(LIFO)
增删元素
皆是在栈顶操作
一次只能删除一个数据项
:当前栈顶元素
只允许访问一个数据项
:当前栈顶元素
实现栈
由于数组大小未知,如果每次插入元素都扩展一次数据(每次扩展都意味着构建一个新数组,然后把旧数组复制给新数组),那么性能消耗相当严重。
这里使用贪心算法,数组每次被填满后,加入下一个元素时,把数组拓展成现有数组的两倍大小。
每次移除元素时,检测数组空余空间有多少。当数组里的元素个数只有整个数组大小的四分之一时,数组减半。
public class Stack {
private int maxSize;
private int top;
private Object[] stackArr;
/**
* 利用构造函数初始化数组
*
* @param maxSize
*/
public Stack(int maxSize) {
this.maxSize = maxSize;
stackArr = new Object[maxSize];
// 相当于栈的指针
top = 0;
}
/**
* 元素出栈
*
* @param i
*/
public void push(Object i) {
if (isFull()) {
throw new RuntimeException("栈已满!");
}
stackArr[top++] = i;
}
/**
* 元素入栈
*
* @return
*/
public Object pop() {
if(isEmpty()) {
throw new RuntimeException("空栈!");
}
// 这里先自减是因为top数组长度,而索引从0开始
return stackArr[--top];
}
/**
* 获取栈顶元素,只是查看,不删除
*
* @return
*/
public Object getTop() {
return stackArr[top - 1];
}
/**
* 判断栈是否为空
*
* @return
*/
public boolean isEmpty() {
return (top == 0);
}
/**
* 判断栈是否已满
*
* @return
*/
public boolean isFull() {
return (top == maxSize);
}
/**
* 回去栈元素的数量
*
* @return
*/
public int length() {
return top;
}
/**
* 清空栈
*
* @return
*/
public void clear() {
while (top != 0) {
pop();
}
}
}
队列
与栈类似:
数组每次被填满后,加入下一个元素时,把数组拓展成现有数组的两倍大小。每次移除元素时,检测数组空余空间有多少。当数组里的元素个数只有整个数组大小的四分之一时,数组减半。
不同之处在于:
由于是先进先出
,移除是从队列的最前端开始的。所以当我们移除数个数据后,队列数据是存储在数组的中间部分的。当队列数据元素个数为整个数组空间的四分之一时,数组减半,且队列数据左移至数组最左端。
数组
特点:查询快
-数据的地址是连续的
通过数组的首地址
可以找到数组,通过数组的索引
可以快速查找到某一个元素
增删慢
-数据的长度固定,增加\删除
元素时,必须创建一个新数组,把源数据复制过来(源数组会在内存中被销毁,垃圾回收
).在堆内存
中频繁创建,复制数组中的元素,销毁数组,效率低下
链表
特点:查询慢
-链表中地址不是连续的
,每次查询元素,都必须从头开始查询
增删快
-链表结构,增加\删除一个元素对链表整体结构没有影响,所以增删快
单向链表
:链表中只有一条
链子,不能保证元素的顺序(存储元素和取出元素有可能不一致)
双向链表
:链表中有两条
链子,有一条专门记录元素的顺序,是一个有序集合
红黑树
二叉树
排序树
平衡树
不平衡树
红黑树
特点:趋近于平衡树
,查询的速度非常快,查询叶子节点最大次数和最小次数不能超过2倍
.
节点
可以是红色
或者黑色
的根节点
是黑色
的叶子节点
(空节点)是黑色
的- 每个
红色节点的子节点
都是黑色
的 任何一个节点
到其每一个叶子节点
的所有路径上黑色节点数
相同