算法基础02:数据结构

队列

队列的使用场景

介绍

实现方式

数组

代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class ArrayQueue{
//队列最大容量
private int maxSize;
//队列尾
private int front;
//队列头
private int rear;
//存放数据的数组
private int[] arr;

/**
* 创建队列的构造器
* @param arrMaxSize
*/
public ArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new int[arrMaxSize];
//指向队列头部,分析出指向的是队列头的前一个位置。即第一个数据的前一个位置
front = -1;
//指向队列尾部数据,即最后一个数据的位置
rear = -1;
}

/**
* 判断队列是否满了
* @return
*/
private boolean isFull(){
return rear == maxSize -1;
}

/**
* 判断队列是否为空
* @return
*/
private boolean isEmpty(){
return rear == front;
}

/**
* 添加数据
* @param n
*/
private void addQueue(int n){
//判断队列是否满了
if (isFull()){
System.out.println("队列满了。。。");
return;
}
arr[rear++] = n;
}

/**
* 获取数据
* @return
*/
private int getQueue(){
//判断队列是否空
if (isEmpty()){
throw new RuntimeException("队列是空的");
}
return arr[front++];
}

/**
* 显式队列的所有数据
*/
private void showQueue(){
//判断队列是否空
if (isEmpty()){
System.out.println("队列是空的。。。");
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.printf("arr[%d]=%d\n",i,arr[i]);
}
}

/**
* 获取头部数据
* @return
*/
public int headQueue(){
//判断队列是否空
if (isEmpty()){
System.out.println("队列是空的。。。");
throw new RuntimeException("队列是空的");
}
return arr[front + 1];
}
}

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public static void main(String[] args) {
//创建一个数组,最大为3
ArrayQueue queue = new ArrayQueue(3);
char key = ' ';
Scanner scanner = new Scanner(System.in);
boolean boo = true;
while (boo){
key = scanner.next().charAt(0);
switch (key){
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int value = scanner.nextInt();
queue.addQueue(value);
break;
case 'g':
try {
int queue1 = queue.getQueue();
System.out.println("取出的数据是:" +queue1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
int queue1 = queue.headQueue();
System.out.println("头数据是:" +queue1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'e':
scanner.close();
boo = false;
break;
default:
break;
}

}
}
存在问题及分析优化
  1. 目前数组使用一次就不能再次使用了,没有达到复用的效果。
  2. 将这个数组使用算法,改进成一个环形数组。

数组模拟环形队列

对前面的数组模拟队列的优化,充分利用数组,因此将数组看做是一个环形的。(通过取模的方式来实现即可)

思路分析

代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
class CircleQueue{

//队列最大容量
private int maxSize;
//队列头,指向队列的第一个元素的位置,初始值0
private int front;
//队列尾,指向最后一个元素的后一个位置,初始值0
private int rear;
//存放数据的数组
private int[] arr;

public CircleQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new int[maxSize];
}

/**
* 判断队列是否满了
* @return
*/
private boolean isFull(){
return (rear + 1) % maxSize == front;
}

/**
* 判断队列是否为空
* @return
*/
private boolean isEmpty(){
return rear == front;
}

/**
* 添加数据
* @param n
*/
public void addQueue(int n){
//判断队列是否满了
if (isFull()){
System.out.println("队列满了。。。");
return;
}
//直接加入
arr[rear] = n;
//rear后移,这里必须考虑取模
rear = (rear + 1) % maxSize;
}

/**
* 获取数据
* @return
*/
public int getQueue(){
//判断队列是否空
if (isEmpty()){
throw new RuntimeException("队列是空的");
}
//这里需要分析出front是指向队列的第一个元素
//1.先把front对应的值保存到一个临时的变量
//2将front后移,考虑取模
//3.将临时变量返回
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}

/**
* 显式队列的所有数据
*/
public void showQueue(){
//判断队列是否空
if (isEmpty()){
System.out.println("队列是空的。。。");
return;
}
//从front开始遍历,
for (int i = front; i < front + size(); i++) {
System.out.printf("arr[%d]=%d\n",i % maxSize,arr[i % maxSize]);
}
}

/**
* 求出当前队列的有效数据的个数
* @return
*/
public int size(){
return (rear + maxSize - front) % maxSize;
}

/**
* 获取头部数据
* @return
*/
public int headQueue(){
//判断队列是否空
if (isEmpty()){
System.out.println("队列是空的。。。");
throw new RuntimeException("队列是空的");
}
return arr[front];
}
}

测试一把

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public static void main(String[] args) {
//创建一个数组,最大为3,设置为4
CircleQueue queue = new CircleQueue(4);
char key = ' ';
Scanner scanner = new Scanner(System.in);
boolean boo = true;
while (boo){
key = scanner.next().charAt(0);
switch (key){
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int value = scanner.nextInt();
queue.addQueue(value);
break;
case 'g':
try {
int queue1 = queue.getQueue();
System.out.println("取出的数据是:" +queue1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
int queue1 = queue.headQueue();
System.out.println("头数据是:" +queue1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'e':
scanner.close();
boo = false;
break;
default:
break;
}

}
}

-------------本文结束感谢您的阅读-------------