2.3 队列
队列是什么
与栈相似,队列也是一种特殊的线性表,与线性表的不同之处也是体现在对数据的增和删的操作上。
队列的特点是先进先出:
先进,表示队列的数据新增操作只能在末端进行,不允许在队列的中间某个结点后新增数据;
先出,队列的数据删除操作只能在始端进行,不允许在队列的中间某个结点后删除数据。也就是说队列的增和删的操作只能分别在这个队列的队尾和队头进行;
两种存储方式
- 顺序队列,依赖数组来实现,其中的数据在内存中也是顺序存储。
- 链式队列,则依赖链表来实现,其中的数据依赖每个结点的指针互联,在内存中并不是顺序存储。链式队列,实际上就是只能尾进头出的线性表的单链表。
案例
约瑟夫环是一个数学的应用问题,具体为,已知 n 个人(以编号 1,2,3...n 分别表示)围坐在一张圆桌周围。从编号为 k 的人开始报数,数到 m 的那个人出列;他的下一个人又从 1 开始报数,数到 m 的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。这个问题的输入变量就是 n 和 m,即 n 个人和数到 m 的出列的人。输出的结果,就是 n 个人出列的顺序
import java.util.LinkedList;
public class QueueTest {
public static void main(String[] args) {
//10个人围成圆桌 从第2个人开始循环报数,数到5的人出列
ring(10, 5, 2);
}
/**
* 用队列解决约瑟夫环问题
*
* @param n 表示人数
* @param m 表示数到m出列
* @param k 第k个开始
*/
public static void ring(int n, int m, int k) {
LinkedList<Integer> queue = new LinkedList<Integer>();
// 初始化n个人
for (int i = 1; i <= n; i++) {
queue.add(i);
}
int element = 0;// 被取出来比对的元素
int i = 0;
for (i = 1; i < k; i++) {
// 因为是从第k个开始,所有将k之前的 出栈,加到栈尾
element = queue.poll();
queue.add(element);
}
i = 1;
while (queue.size() > 0) {
element = queue.poll();
if (i < m) {
//如果不等于m 就添加到栈尾
queue.add(element);
i++;
} else {
//等于m,element就可以出栈了
i = 1;
System.out.println(element);
}
}
}
}