字符串匹配问题:
1.有一个字符串 str1="双喜 double happy 双喜 double happy kairis"
str2="happy 双喜"
问:
判断Str1 是否 有 Str2 如果存在,就返回第一次出现的位置,如果没有,则返回 -1
要求:
用最快的速度来完成匹配
你的思路?
1.如果你没有学过 kmp 算法 你一定是
暴力匹配 即:
happy 匹配 str1 如果总的str2 匹配不上 就从头继续 匹配 这是最简单的实现
这样 需要很多次回头从新匹配 很慢!!
如果你会
KMP算法:
会用一个 部分匹配表 进行匹配 效率将提升!!
数据结构:
线性结构 和 非线性结构
线性结构:
1.数据元素之间存在一对一的线性关系
2.存储结构:
顺序存储结构
链式存储结构
顺序存储的线性表 -> 顺序表 元素是 连续的
链式存储的线性表->链表 元素不一定是连续 存的是:元素+相邻元素的地址
3.有:
数组、队列、链表、栈
非线性结构:
有:
二维数组、多维数组、广义表、树结构、图结构
稀疏数组和队列
编写五子棋程序中 有 存盘退出+续上盘的功能?
你如何实现!
棋盘: 11×11 大小
1.如下左面图 把棋盘保存 该如何做?
注意:
二维数组 :
1表示黑子
2表示蓝子
二维数组有很多默认值是0,记录很多没有意义的数据
---》建议使用 稀疏数组 对二维数组 进行 压缩
稀疏数组:
一个数组中元素 大部分是0 或者为 同一个值得数组 可以使用 稀疏数组 来保存该数组
1.记录数组 一共有几行几列 多少个不同的值
2.把不同值得元素 的 行列值 记录在一个小的数组中 这个小数组 就是 稀疏数组
案例:
6×7 = 42个数据
下图:
稀疏数组: 9×3 =27个数据
第一行 : 有几行 有几列 几个非0的值
其他行:记录非0的元素 所在的 行、列、值、
42-》27 数据压缩了!!!
上面 棋盘的实现思路:
二维数组 转 稀疏数组的思路:
1. 遍历 原始的二维数组,得到有效数据的个数 sum
2. 根据sum 就可以创建 稀疏数组 sparseArr int[sum + 1] [3]
3. 将二维数组的有效数据数据存入到 稀疏数组
稀疏数组转原始的二维数组的思路 :
1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的
chessArr2 = int [11][11]
2. 在读取稀疏数组后几行的数据,并赋给 原始的二维数组 即可.
java: 二维数组 转 稀疏数组
package datastructure;
public class SparseArrayApp {
public static void main(String[] args) {
/**
* 11*11
* 1 黑子
* 2 篮子
*/
System.out.println("-----二维数组 -> 稀疏数组-----");
int[][] chessArrRaw = new int[11][11];
chessArrRaw[1][2] =1;
chessArrRaw[2][3] =2;
System.out.println("原始的二维数组:");
for (int[] row : chessArrRaw) {
for (int data : row) {
System.out.printf("%d\t",data);
}
System.out.println();
}
/**
* 二维数组 -> 稀疏数组
* 1.遍历二维数组 得到非0数据的个数
*/
int count = 0;
for (int i = 0; i < chessArrRaw.length; i++) {
for (int j = 0; j < chessArrRaw.length; j++) {
if (chessArrRaw[i][j] != 0) {
count++;
}
}
}
System.out.println("二维数组的非0元素的个数: count=" +count);
//2.创建稀疏数组 赋值
int[][] sparseArr = new int[count + 1][3];
sparseArr[0][0]= chessArrRaw.length;
sparseArr[0][1]= chessArrRaw.length;
sparseArr[0][2]= count;
int flag =0;//记录是 第几个非0 的数据
for (int i = 0; i < chessArrRaw.length; i++) {
for (int j = 0; j < chessArrRaw.length; j++) {
if (chessArrRaw[i][j] != 0) {
flag++;
sparseArr[flag][0] =i; //行
sparseArr[flag][1] =j; //列
sparseArr[flag][2] =chessArrRaw[i][j]; //值本身
}
}
}
//输出稀疏数组
System.out.println("稀疏表为:");
for (int i = 0; i < sparseArr.length; i++) {
System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
}
/**
* 稀疏数组 -> 二维数组
*/
System.out.println();
System.out.println("-----稀疏数组 -> 二维数组-----");
int[][] chessArrRes = new int[sparseArr[0][0]][sparseArr[0][1]];
// 从稀疏数组的第二行开始 取值 并赋值给二维数组
for (int i = 1; i
结果:
-----二维数组 -> 稀疏数组-----
原始的二维数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
二维数组的非0元素的个数: count=2
稀疏表为:
11 11 2
1 2 1
2 3 2
-----稀疏数组 -> 二维数组-----
恢复的二维数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
scala 代码: 二维数组 转 稀疏数组
里面我添加了 scala 遍历的高级写法
package com.datastructure
object SparseArrayApp {
def main(args: Array[String]): Unit = {
println("----二维数组 -> 稀疏数组----")
println()
val chessArrRaw: Array[Array[Int]] = Array.ofDim[Int](11,11)
chessArrRaw(1)(2)=1
chessArrRaw(2)(3)=2
println("原始的二维数组: ")
for(row <- chessArrRaw) {
for(data <- row) {
printf("%d\t",data)
}
println()
}
/* println("原始的二维数组: ")
chessArrRaw.init.map(row =>{
row.indices.map(i=>printf("%d\t",row(i)))
println()
})*/
//二维数组-> 稀疏数组
var count =0
for(i <- 0 until chessArrRaw.size) {
for(j <- 0 until chessArrRaw.size) {
if(chessArrRaw(i)(j) != 0){
count = count +1
}
}
}
println(s"二维 数组非0元素个数: Count=${count}")
val sparseArr = Array.ofDim[Int](count+1,3)
sparseArr(0)(0)=chessArrRaw.length
sparseArr(0)(1)=chessArrRaw.length
sparseArr(0)(2)=count
var flag = 0
for(i <- 0 until chessArrRaw.size) {
for(j <- 0 until chessArrRaw.size) {
if(chessArrRaw(i)(j) != 0){
flag = flag+1
sparseArr(flag)(0)=i
sparseArr(flag)(1)=j
sparseArr(flag)(2)=chessArrRaw(i)(j)
}
}
}
//输出 稀疏数组
println("稀疏表为:")
for(i<- 0 until sparseArr.length) {
printf("%d\t%d\t%d\t\n",sparseArr(i)(0),sparseArr(i)(1),sparseArr(i)(2))
}
/* sparseArr.indices.map(i => {
printf("%d\t%d\t%d\t\n",sparseArr(i)(0),sparseArr(i)(1),sparseArr(i)(2))
})*/
/**
* 稀疏数组 -> 二维数组
*/
println()
println("----稀疏数组 -> 二维数组----")
val chessRes = Array.ofDim[Int](sparseArr(0)(0),sparseArr(0)(1))
sparseArr.indices.filter( i => i!=0).map(i=>{
chessRes(sparseArr(i)(0))(sparseArr(i)(1)) = sparseArr(i)(2)
})
//遍历
chessRes.init.map(row =>{
row.indices.map(i=>printf("%d\t",row(i)))
println()
})
}
}
结果:
----二维数组 -> 稀疏数组----
原始的二维数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
二维 数组非0元素个数: Count=2
稀疏表为:
11 11 2
1 2 1
2 3 2
----稀疏数组 -> 二维数组----
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
稀疏数组总结:
1.这个技巧 节省空间 提升效率
队列
特点:
先进先出(先存入队列的数据 要先取出)
eg:使用场景
银行排队 叫号系统
1.队列是一个有序列表 可以用数组 或者 链表来实现
数组:=》 顺序存储
链表:=>链式存储
使用数组模拟环形队列:
1.队列:
front:表示队列的头部
rear:表示队列的尾部
2.第二个图:表示当 有数据 添加进来的时候
front 不变
rear 位置增加
3.第三个图:
表示从 队列 取数据的情况
是从 front 开始取出
注意:
加数据 -> rear
取数据 -> front
数组模拟队列:
java:
package datastructure;
import java.util.Scanner;
public class ArrayQueueApp {
public static void main(String[] args) {
ArrayQueue queue = new ArrayQueue(3);
char insert = ' ';//接受 用户的输入
Scanner scanner = new Scanner(System.in);
boolean loop =true;
//菜单
while (loop){
System.out.println("s(show): 显示队列");
System.out.println("e(exit): 退出程序");
System.out.println("a(add): 添加数据到队列");
System.out.println("g(get): 从队列取出数据");
System.out.println("h(head): 队列头");
System.out.println("l(show): 列出队列数据");
insert = scanner.next().charAt(0);
switch (insert) {
case 's':
queue.showQueue();
break;
case 'e':
scanner.close();
loop=false;
break;
case 'a':
System.out.println("输入一个数:");
int value = scanner.nextInt();
queue.addQueue(value);
System.out.println("添加完成");
break;
case 'g':
try {
System.out.printf("取出的数据是%d\n", queue.getQueue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
System.out.printf("queue head 数据是%d\n", queue.headQueue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'l':
queue.showQueue();
default:
break;
}
}
System.out.println("---程序退出---");
}
}
//
class ArrayQueue{
private int maxSize;
private int front;
private int rear;
private int[] data; //用于存放数据 模拟队列
public ArrayQueue(int arrMaxSize) {
this.maxSize = arrMaxSize;
this.data = new int[maxSize];
this.front =-1; //指向队列头部 的前一个位置
this.rear = -1;// 指向队列尾部 指向队列尾部的 具体的位置
}
public boolean isFull(){
return rear == maxSize -1 ;
}
public boolean isEmpty(){
return rear == front;
}
public void addQueue(int num){
if(isFull()){
System.out.println("队列已经满了,不能添加数据");
return;
}
rear++; //rear 后移
data[rear] = num;
}
public int getQueue(){
if(isEmpty()){
System.out.println("队列是空的");
throw new RuntimeException("队列是空的");
}
front++; //后移 front
return data[front];
}
public void showQueue(){
if(isEmpty()){
System.out.println("队列是空的");
return;
}
for (int i = 0; i < data.length; i++) {
System.out.printf("data[%d]=%d\n",i,data[i]);
}
}
public int headQueue(){
if (isEmpty()){
System.out.println("队列是空的");
throw new RuntimeException("队列是空的");
}
return data[front + 1];
}
}
结果:
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
队列是空的
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
10
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
20
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
30
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
data[0]=10
data[1]=20
data[2]=30
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
h
queue head 数据是10
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
g
取出的数据是10
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
data[0]=10
data[1]=20
data[2]=30
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
h
queue head 数据是20
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
l
data[0]=10
data[1]=20
data[2]=30
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
scala:
package com.datastructure
import java.util.Scanner
object ArrayQueueApp {
def main(args: Array[String]): Unit = {
val queue = new ArrayQueue(3)
var insert:Char = ' '
var loop = true
val scanner = new Scanner(System.in)
while (loop){
println("s(show): 显示队列")
println("e(exit): 退出程序")
println("a(add): 添加数据到队列")
println("g(get): 从队列取出数据")
println("h(head): 队列头")
println("l(show): 列出队列数据")
insert = scanner.next().charAt(0)
insert match {
case 's' => queue.showQueue()
case 'e' =>{
scanner.close()
loop = false
}
case 'a' =>{
println("输入一个数:")
val value = scanner.nextInt
queue.addQueue(value)
println("添加完成")
}
case 'g' =>
try
printf("取出的数据是%d\n", queue.getQueue)
catch {
case e: Exception =>
println(e.getMessage)
}
case 'h' =>
try
printf("queue head 数据是%d\n", queue.headQueue)
catch {
case e: Exception =>
println(e.getMessage)
}
case 'l' =>
queue.showQueue()
case _ =>
}
}
println("---程序退出---")
}
}
class ArrayQueue{
private var maxSize:Int =_
private var front:Int =_
private var rear:Int =_
private var data:Array[Int] =_
def this(arrMaxSize:Int){
this()
this.maxSize = arrMaxSize
data = Array.ofDim[Int](maxSize)
front = -1
rear = -1
}
def isFull()={
rear == maxSize -1
}
def isEmpty()={
rear == front
}
def addQueue(num : Int)={
if(isFull()){
println("队列是满的 不能添加")
}
rear = rear +1
data(rear) = num
}
def getQueue() ={
if(isEmpty()){
throw new RuntimeException("队列是空的")
}
front = front +1
data(front)
}
def showQueue() : Unit={
if(isEmpty()){
println("队列是空的")
return
}
data.indices.map(i =>{
printf("data[%d]=%d\n",i,data(i))
})
}
def headQueue()={
if(isEmpty()){
throw new RuntimeException("队列是空的")
}
data(front + 1)
}
}
结果:
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
队列是空的
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
10
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
20
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
30
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
data[0]=10
data[1]=20
data[2]=30
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
g
取出的数据是10
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
g
取出的数据是20
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
g
取出的数据是30
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
队列是空的
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
10
队列是满的 不能添加
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at com.datastructure.ArrayQueue.addQueue(ArrayQueueApp.scala:91)
at com.datastructure.ArrayQueueApp$.main(ArrayQueueApp.scala:34)
at com.datastructure.ArrayQueueApp.main(ArrayQueueApp.scala)
注意:
数组模拟队列:
从上面的结果看 有一个很大的问题:
1. 取出的数据 0 1 位置的 之后 0 1 这两个位置就用不了
2. 满了之后 再添加 添加不进去
3. 你的这个数组 只用了 一次 !!
当然你会觉得是代码问题!! 没有做成环形的队列!
数组模拟队列 ->做成 环形队列 是需要算法的
优化:
把 数组 取出的 空间能够复用
因为之前 取出之后 之前的空间存的数据 就是无效数据了
环形队列:
思路如下:
1. front 变量的含义做一个调整:
front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
front 的初始值 = 0
2. rear 变量的含义做一个调整:
rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
rear 的初始值 = 0
3. 当队列满时,条件是 (rear + 1) % maxSize == front 【满】
3这个 很好理解:
rear +1 就是 约定 最后一个元素+1 如果等于 maxsize
front 不动 为0的时候 ,就是队列 一个数也没有取出
取模之后 就是等于 front
一定要注意:
rear 指向队列的最后一个元素的后一个位置
这是一个环形队列
4. 对队列为空的条件, rear == front 空
5. 当我们这样分析, 队列中有效的数据的个数
(rear + maxSize - front) % maxSize // rear = 1 front = 0
我们就可以在原来的队列上修改得到,一个环形队列
java:
package datastructure;
import java.util.Scanner;
public class CircleArrayQueueApp {
public static void main(String[] args) {
CircleArrayQueue queue = new CircleArrayQueue(3);
char insert = ' ';//接受 用户的输入
Scanner scanner = new Scanner(System.in);
boolean loop =true;
//菜单
while (loop){
System.out.println("s(show): 显示队列");
System.out.println("e(exit): 退出程序");
System.out.println("a(add): 添加数据到队列");
System.out.println("g(get): 从队列取出数据");
System.out.println("h(head): 队列头");
System.out.println("l(show): 列出队列数据");
insert = scanner.next().charAt(0);
switch (insert) {
case 's':
queue.showQueue();
break;
case 'e':
scanner.close();
loop=false;
break;
case 'a':
System.out.println("输入一个数:");
int value = scanner.nextInt();
queue.addQueue(value);
System.out.println("添加完成");
break;
case 'g':
try {
System.out.printf("取出的数据是%d\n", queue.getQueue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
System.out.printf("queue head 数据是%d\n", queue.headQueue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'l':
queue.showQueue();
default:
break;
}
}
System.out.println("---程序退出---");
}
}
//
class CircleArrayQueue {
private int maxSize;
private int front;
private int rear;
private int[] data; //用于存放数据 模拟队列
public CircleArrayQueue(int arrMaxSize) {
this.maxSize = arrMaxSize;
this.data = new int[maxSize];
this.front =0;
this.rear = 0;
}
public boolean isFull(){
return (rear +1)% maxSize == front ;
}
public boolean isEmpty(){
return rear == front;
}
public void addQueue(int num){
if(isFull()){
System.out.println("队列已经满了,不能添加数据");
return;
}
data[rear] = num;
//将rear后移 必须考虑取模 因为 取模是为了 消除无效的数据
rear = (rear+1) % maxSize;
}
public int getQueue(){
if(isEmpty()){
System.out.println("队列是空的");
throw new RuntimeException("队列是空的");
}
//分析 是指向 队列的第一个元素 取出 再后移嘛
int value = data[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("data[%d]=%d\n",i % maxSize,data[i % maxSize]);
}
}
//当前有效数据的个数
public int size(){
return (rear+maxSize -front) % maxSize;
}
public int headQueue(){
if (isEmpty()){
System.out.println("队列是空的");
throw new RuntimeException("队列是空的");
}
return data[front];
}
}
scala:
package com.datastructure
import java.util.Scanner
object CircleArrayQueueApp {
def main(args: Array[String]): Unit = {
val queue = new CirleArrayQueue(3)
var insert:Char = ' '
var loop = true
val scanner = new Scanner(System.in)
while (loop){
println("s(show): 显示队列")
println("e(exit): 退出程序")
println("a(add): 添加数据到队列")
println("g(get): 从队列取出数据")
println("h(head): 队列头")
println("l(show): 列出队列数据")
insert = scanner.next().charAt(0)
insert match {
case 's' => queue.showQueue()
case 'e' =>{
scanner.close()
loop = false
}
case 'a' =>{
println("输入一个数:")
val value = scanner.nextInt
queue.addQueue(value)
println("添加完成")
}
case 'g' =>
try
printf("取出的数据是%d\n", queue.getQueue)
catch {
case e: Exception =>
println(e.getMessage)
}
case 'h' =>
try
printf("queue head 数据是%d\n", queue.headQueue)
catch {
case e: Exception =>
println(e.getMessage)
}
case 'l' =>
queue.showQueue()
case _ =>
}
}
println("---程序退出---")
}
}
class CirleArrayQueue{
private var maxSize:Int =_
private var front:Int =_
private var rear:Int =_
private var data:Array[Int] =_
def this(arrMaxSize:Int){
this()
this.maxSize = arrMaxSize
data = Array.ofDim[Int](maxSize)
front = 0
rear = 0
}
def isFull()={
(rear +1)%maxSize == front
}
def isEmpty()={
rear == front
}
def addQueue(num : Int) :Unit={
if(isFull()){
System.out.println("队列已经满了,不能添加数据")
return
}
data(rear) = num
rear = (rear +1) % maxSize
}
def getQueue() ={
if(isEmpty()){
throw new RuntimeException("队列是空的")
}
val value = data(front)
front = (front +1) % maxSize
value
}
def showQueue() : Unit={
if(isEmpty()){
println("队列是空的")
return
}
for(i <- front until front+size() ){
printf("data[%d]=%d\n",i % maxSize,data(i % maxSize))
}
}
def size()={
(rear +maxSize -front) % maxSize
}
def headQueue()={
if(isEmpty()){
throw new RuntimeException("队列是空的")
}
data(front)
}
}
结果:
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
10
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
20
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
30
队列已经满了,不能添加数据
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
data[0]=10
data[1]=20
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
g
取出的数据是10
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
g
取出的数据是20
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
队列是空的
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
a
输入一个数:
20
添加完成
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
s
data[2]=20
s(show): 显示队列
e(exit): 退出程序
a(add): 添加数据到队列
g(get): 从队列取出数据
h(head): 队列头
l(show): 列出队列数据
总结:
环形队列:
1. rear 和 front 后移的时候 要考虑 取模!!! 、
即:
front = (front +1 ) % maxSize
2. 有效数据的个数
(rear+maxSize -front) % maxSize
3. 取值
直接取值即可
data(front) = 》 头
data(reat) =》 就是 尾部
添加的时候 要后移!!! 这根代码有关
4.遍历 队列
从 front 开始遍历 遍历多少个元素:
1.当前有效数据的个数
(rear+maxSize -front) % maxSize = size()
2.front + size() 就是 从front开始遍历 的结尾
3.
//从 front 开始遍历 遍历多少个元素
for (int i = front; i < front + size(); i++) {
System.out.printf("data[%d]=%d\n",i % maxSize,data[i % maxSize]);
}
下标:
i % maxSize 记得是要考虑取模的
5.约定预留 要注意!!