目录
* 数组
* 链表
* 栈和队列
* 二叉树
* 堆和堆栈
* 散列表
* 红黑树
数组
数组是一种连续存储线性结构,元素类型相同,大小相同,数组是多维的,通过整形索引值(即下标index)来访问其元素,数组的大小不能改变。
-
数组的优点
1、存取速度快 2、定义简单 3、能存储大量数据
-
数组的缺点
1、事先必须知道数组的长度。 2、数组中所有的类型必须相同。 3、增删元素比较慢。 4、需要大块连续的内存空间,所以数组不可能定义的太大,因为内存中不可能有那么多大的连续的内存空间, 而解决这个问题的方法就是使用链表。
链表
链表是一种非连续、非顺序的存储结构。
每个链表中包含多个离散节点,节点之间通过指针相连。
每个节点只有一个前驱节点,只有一个后续节点,首节点没有前驱节点,尾结点没有后续节点。
每个节点都是一个对象,可以分为两部分:数据域和指针域。
数据域用来存储数据
指针域用来存储节点地址信息
-
链表的优点
1、空间没有限制 2、增删数据效率快
-
链表的缺点
1、查、取数据速率慢
链表的种类
-
单链表
一个节点指向下一个节点
-
双向链表
一个节点有两个指针域
-
循环链表
能够通过任意一个节点找到其他所有节点,即将两种链表的尾节点指向第一个节点, 而实现循环。
单链表的实现
双链表的实现
循环链表的实现
数组与链表的区别
1、在访问方式上
数组可以随机访问其中的元素;
链表则必须是顺序访问,不能随机访问。
2、空间的使用上
链表可以随意扩大;
数组则不能。
栈和队列
数组和列表都是线性存储结构的基础,栈和队列则是他们的应用。
栈
-
什么是栈
Java中把内存分为两种,一种是栈内存,一种是堆内存。 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 堆内存用于存放由new创建的数组和对象。 堆和栈都是java在Ram(计算机内存)中用来存放数据的地方,java自动管理堆和栈,程序 员不能直接设置。 栈的优点是:存取速度比较快,缺点是:存在栈中的数据的大小和生命周期必须是确定 的,缺乏灵活性。
栈是一种运算受限的线性表,其限制是仅允许在表的一端进行插入删除操作,这一端被称为栈顶,相对端为栈底,不含任何元素的栈称为空栈。
- 往栈里放东西称为进栈。
- 从栈里拿东西称为出栈。
- 栈就是一个桶,后放进去的先拿出来(后进先出),它下面本来有的东西要等它出来之后才能出来(先进后出)
java实现栈
- 由数组实现的栈叫做:
静态栈
- 由链表实现的栈叫做:
动态栈
静态栈的实现
动态栈的实现
队列
队列的概念就比较容易理解了,我们可以理解为排队打饭:
- 有新的人加入了叫做
入队
- 队首的人打完饭了离开叫做
出队
队列的特点即为:先进先出,后进后出。
-
使用数组实现的叫做
静态对列
-
使用链表实现的叫做
动态对列
那么实现队列有几种方式呢?有两种方式:一种是使用了阻塞算法的阻塞队列(如上文中 的吃饭的时候等待着老板把饭菜做好);另一种是使用非阻塞算法(在老板告知需要等待 的时候,你去干自己的事,等饭菜做好再来就餐)。
静态对列的实现
public class Queue<E> {
private Object[] data=null;
private int maxSize; //队列容量
private int front; //队列头,允许删除
private int rear; //队列尾,允许插入
//构造函数
public Queue(){
this(5);
}
public Queue(int initialSize){
if(initialSize >=0){
this.maxSize = initialSize;
data = new Object[initialSize];
front = rear =0;
}else{
throw new RuntimeException("初始化大小不能小于0:" + initialSize);
}
}
//判空
public boolean empty(){
return rear==front?true:false;
}
//入队
public boolean add(E e){
if(rear== maxSize){
throw new RuntimeException("队列已满,无法插入新的元素!");
}else{
data[rear++]=e;
return true;
}
}
//出队
public E poll(){
if(empty()){
throw new RuntimeException("空队列异常!");
}else{
E value = (E) data[front]; //保留队列的front端的元素的值
data[front++] = null; //释放队列的front端的元素
return value;
}
}
//队列长度
public int length(){
return rear-front;
}
/**
* 遍历队列
* @param queue
*
*/
public static void traverseQueue(Queue queue) {
// front的位置
int i = queue.front;
while (i != queue.rear) {
System.out.println("队列值:" + queue.data[i]);
//移动front
i = (i + 1) % queue.data.length;
}
}
}
二叉树
堆和堆栈
- 堆内存放的是由new创建的数组和对象。
- 在堆内分配的内存,由java虚拟机的自动垃圾回收器来管理。
- 堆栈就是栈,称呼不同而已。
栈和堆的特点
-
栈的优点
存取速度比较快
-
栈的缺点
存在栈中的数据的大小和生命周期必须是确定的,缺乏灵活性。
-
堆的优点
可以动态分配内存的大小,生命周期也不用事先告诉编辑器,java垃圾回收器会自动回 收这些不再使用的数据。
-
堆的缺点
由于动态分配内存,所以存取速度慢。
散列表
一提起散列表,我们就能联想到set和map,以及HashSet和HashMap。
散列表作用:
由于数组和链表都可以按照人们的意愿有序排列数据,他们是有序的,但有次而来的问题是:
想要获取某个元素,就要遍历所有的数据,直到找到为止,会消耗很多时间。所以我们需要
另外的存储结构,不在意元素的顺序,能快速查找数据,其中一个方法就是:散列表。
散列表的原理
散列表中每个对象计算出一个整数,即散列码,对象根据计算出来的整数(散列码)保存在对应位置上,即这些散列码就是索引。
在java中,散列表是用链表数组实现的,每个列表称之为桶。
红黑树
红黑树是特殊的二叉查询树,红黑树的特点:
- 节点是红色或黑色
- 根节点是黑色
- 每个叶节点(NUL节点、空节点)都是黑色。
- 每个红节点的两个子节点都是黑色。
- 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。