栈是一种只能在一端进行插入或删除操作的线性表。表中允许进行插入、删除操作的一端称为栈顶
栈的修改是按照后进先出的原则进行的,栈又称为后进先出的线性表。
栈顶的当前位置是动态的,栈顶的当前位置由一个称为栈顶指针的位置指示器指示。表的另一端称为栈底。
当栈中没有数据元素时,称为空栈。
栈的插入操作通常称为进栈,栈的删除操作通常 称为出栈。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wSGzsKn2-1609764859962)(E:\StudySource\数据结构\栈和队列\图像\栈的示意图.png)]
例3.1 设一个栈的输入序列为A,B,C,D,则借助一个栈所得到的输出序列不可能是 。
(A) A,B,C,D (B) D,C,B,A
(C) A,C,D,B (D) D,A,B,C
//D
例3.2 已知一个栈的进栈序列是1,2,3,…,n,其输出序列是p1,p2,…,pn,若p1=n,则pi的值 。
(A) i (B) n-i
(C) n-i+1 (D) 不确定
//C
ADT Stack {
数据对象:
D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 }
数据关系:
R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n }
约定an 端为栈顶,a1 端为栈底。
基本操作:
InitStack(&S)初始化栈
DestroyStack(&S)销毁栈
StackLength(S)获得栈长度
StackEmpty(S)判空
GetTop(S,&e)得到栈顶元素
ClearStack(&S)清空栈元素
Push(&s,e)进栈
Pop(&S,&e)出栈
StackTravers(S)遍历:从下往上
//----- 栈的顺序存储表示 -----
#define STACK_INIT_SIZE 100;
#define STACKINCREMENT 10;
typedef struct {
int *base; //栈底
int *top; //栈顶
int stacksize; // 栈大小
} SqStack;
int InitStack (SqStack &S)
{// 构造一个空栈S
S.base=(int*)malloc(STACK_INIT_SIZE* sizeof(int));
if (!S.base) exit (-2); //存储分配失败
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return 1;
}
int ClearStack(SqStack &S)
{ /* 把S置为空栈 */
S.top=S.base;
return 1;
}
int StackEmpty(SqStack S)
{ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
if(S.top==S.base)
return 1;
else
return 0;
}
int StackLength(SqStack S)
{ /* 返回S的元素个数,即栈的长度 */
return S.top-S.base;
}
int GetTop(SqStack S, int &e)
{
if(S.top>S.base)
{
e=*(S.top-1);
return 1;
}
else
return 0;
}
int Push (SqStack &S, SElemType e) {
if (S.top - S.base >= S.stacksize) {//栈满,追加存储空间
S.base = (ElemType *) realloc ( S.base,
(S.stacksize + STACKINCREMENT) *
sizeof (int));
if (!S.base) exit (OVERFLOW); //存储分配失败
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
return 1;
}
int Pop (SqStack &S, int &e) {
// 若栈不空,则删除S的栈顶元素,
// 用e返回其值,并返回 1;
// 否则返回 0
if (S.top == S.base) return 0;
S.top--;
e = *S.top;
return 1;
}
int StackTraverse(SqStack S)
{ int *p;
p=S.base;
while(p
十进制数N----->d进制数的原理:
N = (N div d)*d + N mod d
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rh19nu1N-1609764859966)(E:\StudySource\数据结构\栈和队列\图像\数制转换.png)]
public static int transformation(int number) {
Stack<Integer> s = new Stack<Integer>();
while(number != 0) {
s.push(number % 8);//将余数入栈
number /= 8;//除模
}
int result = 0;
while(s.size() != 0) {
//System.out.println(s.pop());
result += s.pop() * Math.pow(10, s.size());//出栈并拼接数值
}
return result;
}
import java.util.Stack;
/*
* 字符串是否回文
*/
public class StringSymmetric {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(stringSymmetric("123456654321"));
}
public static boolean stringSymmetric(String s) {
//1.如果字符串为空,或者长度不大于1,返回false(不回文)
if(s==null || s.length() <=1) {
return false;
}
Stack<Character> stack = new Stack<Character>();
//2.字符串转换成字符数组
char [] c = s.toCharArray();
//3.字符数组单个入栈
for(char cc:c) {
stack.push(cc);
}
//4.字符数组出栈(即为反向输出),逐个对比,如果有不一致,返回false
for(char cc:c) {
if(cc != stack.pop())
return false;
}
//5.如果第四步正常结束,此时字符串回文,返回true
return true;
}
}
import java.util.Scanner;
import java.util.Stack;
/*
* 在用户输入一行的过程中,允许用户输入出差错,并在发现有误时可以及时更正。
* 合理的做法:
* 设立一个输入缓冲区,
* 用以接受用户输入的一行字符,
* 然后逐行存入用户数据区,
* 并假设“#”为退格符,“@”为退行符。
* 假设从终端接受了这样两行字符:
* whli##ilr#e(s#*s)
* outcha@putchar(*s=#++);
* 则实际有效的是下列两行:
* while (*s)
* putchar(*s++);
*
*/
public class EditTransformation {
public static void main(String[] args) {
//定义输入工具类对象
Scanner reader = new Scanner(System.in);
System.out.println("请输入:");
System.out.println(transformation(reader.next()));
}
public static String transformation(String s) {
//1.声明栈
Stack stack = new Stack();
//2.生成字符数组
char [] c = s.toCharArray();
//3.遍历字符数组,对输入的字符串信息进行处理
for(char cc:c) {
//当遇到回车换行字符时,表示输入结束
if(cc=='\n') {
break;
}
//如果没有结束,根据不同的字符对栈进行不同的操作
//@删除栈顶元素
//#清空栈
//default入栈
switch(cc) {
case '@':{//如果栈不为空,输出栈顶
if(stack.size()!=0) {
stack.pop();
break;
}
}
case '#':{
stack.clear();
break;
}
default:{
stack.push(cc);
break;
}
}
}
//4.从栈底到栈顶遍历
String result = "";
for(int i = 0; i < stack.size();i++) {
result += stack.get(i);
}
return result;
}
}
package com.gavin.stack;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;
public class ExcepssionGetEvaluation {
/**
* 存放数值的栈
*/
private static Stack<Float> numberStack = new Stack<Float>();
/**
* 存放运算符的栈
*/
private static Stack<String> andCalcStack = new Stack<String>();
/**
* 运算符优先级map集合
*/
private static final Map<String,Integer> OPT_PRIORITY_MAP = new HashMap<String,Integer>(){
{
put("(",0);
put("+",2);
put("-",2);
put("*",3);
put("/",3);
put(")",7);
put("=",20);
}
};
/**
* 如果栈顶元素是“=”,直接入栈
* 运算符优先级比较,当前运算符和栈顶运算符优先级对比,
* 如果大于栈顶元素优先级,可以入栈
* 执行一次运算,然后递归继续判断
* @param currentAndCalc 当前运算符
*/
public static void compareAndCalc(String currentAndCalc){
//出口
//判断栈运算符栈是否还有其他运算符:如果栈顶为“=”直接跳出递归
if(andCalcStack.peek().equals("=")) {
andCalcStack.push(currentAndCalc);
return;
}
//1.获取当前栈顶运算符的优先级值
int value = OPT_PRIORITY_MAP.get(andCalcStack.peek());
//2.根据优先级进行不同的操作
//如果优先级大于栈顶元素优先级,运算符入栈
if(OPT_PRIORITY_MAP.get(currentAndCalc) > value) {
andCalcStack.push(currentAndCalc);
}
//如果优先级小于或等于栈顶元素优先级,执行一次二元运算
else {
//将运算结果入栈
numberStack.push(calculate());
//执行递归继续判断
compareAndCalc(currentAndCalc);
}
}
/**
* 判断字符串是否是数值,如果能转换成数值型,
* 返回数值,抛出异常代表转换失败,不是数值,返回-1
* @param token 当前字符串
* @return 数值,为-1表示不是数值
*/
public static float isNumber(String token) {
//将字符串转换成数值,如果不抛出异常表示是数,否则不是数值
try {
float f = Float.parseFloat(token);
return f;
}
catch (Exception e) {
return -1.0f;
}
}
/**
* 进行四则运算,根据不同运算符,执行不同的操作
* 在除法运算时,分母为0时,抛出异常,分母不能为0
* @return 运算结果
*/
public static float calculate() {
try {
//获得运算符
String andCalc = andCalcStack.pop();
//获得第二个运算数
float b = numberStack.pop();
//获得第一个运算数
float a = numberStack.pop();
if(andCalc.equals("+")) {
return a + b;
}
else if(andCalc.equals("-")) {
return a - b;
}
else if(andCalc.equals("*")) {
return a * b;
}
else{
if(b==0.0f) {
throw new RuntimeException("表达式有误,分母不能为0!");
}
return a / b;
}
}
catch (Exception e) {
System.out.println("运算出现错误,请检查表达式是否有误!");
}
return 0.0f;
}
/**
* 将表达式字符串切割成字符数组
* @param input
* @return 字符串数组
*/
public static String[] getInput(String input) {
//1.切割表达式字符串,如果抛出异常,提示输入有误
try {
String [] inputSplits = input.split(" ");
//2.遍历字符串数组,输出表达式
System.out.print("运算表达式:");
for(String s:inputSplits) {
System.out.print(s+" ");
}
System.out.println();
//3.返回运算表达式数组
return inputSplits;
}
catch(Exception e){
System.out.println("输入有误,程序终止!!!");
System.exit(-1);//终止运行
}
return null;
}
/**
* 计算表达式的值,使用两个栈:数值栈和运算符栈
* @param express 表达式字符数组
* @return 运算结果
*/
public static float canculate(String [] expression) {
//2.遍历表达式数组,完成运算
for(String s:expression) {
//如果是数值,放入值栈中
if(isNumber(s) != -1.0) {
numberStack.push(isNumber(s));
}
//否则就是运算符
//判断运算符的类型,执行不同的操作
else {
if(s.equals("(")) {
//当前运算符是左括号,直接入栈
andCalcStack.push("(");
}
else if(s.equals(")")) {
//如果是右括号,递归计算,知道遇到左括号为止
directCalc();
}
else {
//正常运算符,判断如何入栈
compareAndCalc(s);
}
}
}
//3.当遍历完表达式数组后,判断是否运算结束
//如果栈顶不是等号,表示运算没有完成使用while循环继续运算,
//遇到等号结束
while(!andCalcStack.peek().equals("=")) {
//计算结果入栈
numberStack.push(calculate());
}
//4.循环结束时,运算完成,返回运算结果
return numberStack.peek();
}
/**
*寻找左括号递归运算
*/
public static void directCalc() {
//1.遇到左括号,左括号出栈,递归终止
if(andCalcStack.peek().equals("(")) {
andCalcStack.pop();//删除栈顶左括号
}
//2.否则执行四则运算
else {
//将运算结果入栈
numberStack.push(calculate());
//执行递归继续判断是否继续运算
directCalc();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// try {
// System.out.println(calculate(5, 0, "/"));
// }
// catch (Exception e) {
// System.out.println(e);
// }
Scanner reader = new Scanner(System.in);
System.out.print("请输入表达式(数值字符之间用空格隔开):");
String input = reader.nextLine();
andCalcStack.push("=");
//计算获得结果
float result = canculate(getInput(input));
System.out.println("运算结果:" + result);
}
}
1.当在一个函数的运行期间调用另一个函数时,在运行该被调用函数之前,
需先完成三项任务:
[1].将所有的实在参数、返回地址等信息传递给被调用函数保存;
[2].为被调用函数的局部变量分配存储区;
[3].将控制转移到被调用函数的入口;
2.从被调用函数返回调用函数之前,应该完成下列三项任务:
[1].保存被调函数的计算结果;
[2].释放被调函数的数据区;
[3].依照被调函数保存的返回地址将控制转移到调用函数。
3.多个函数嵌套调用的规则是:
后调用先返回!
此时的内存管理试行**“栈式管理”**:先调用的后返回,后调用的先返回。
1.打印输出所有四位二进制数
package com.gavin.stack;
public class AllFourSiteOfBinary {
/**
* 二进制数字符表示数组
*/
private static char [] s = new char[5];
/**
* 纪录总数
*/
private static int sum = 0;
/**
* 递归函数
* @param n 当前第几位数字
*/
public void fun(int n) {
if(n==4){
print();
}
else {
//递归当前位为0的所有结果
s[n] = '0';
fun(n+1);
//递归当前位为1的所有结果
s[n] = '1';
fun(n+1);
}
}
/**
* 打印输出
*/
public void print() {
for(int i = 0; i < s.length;i++) {
System.out.print(s[i]);
}
sum++;
}
/**
* 主函数
* @param args
*/
public static void main(String[] args) {
s[4] = '\n';//用于回车换行打印
AllFourSiteOfBinary allFourSiteOfBinary = new AllFourSiteOfBinary();
allFourSiteOfBinary.fun(0);
System.out.println("总共有"+sum+"个四位二进制数!");
}
}
2.斐波那切数列
1,1,2,3,5,8,13,21,34,55,...
F 1 = F 2 = 1 ; F_1 = F_2 = 1; F1=F2=1;
F n = F ( n − 1 ) + F ( n − 2 ) , n > 2 ; F_n = F_(n-1) + F_(n-2),n >2; Fn=F(n−1)+F(n−2),n>2;
package com.gavin.stack;
public class FibonacciSequence {
public int fun(int n) {
if(n < 1) {
return 0;
}
if(n==1 || n==2) {
return 1;
}
else {
return fun(n-1) + fun(n - 2);
}
}
public static void main(String[] args) {
FibonacciSequence fibonacciSequence = new FibonacciSequence();
for(int i = 1; i <= 10; i++) {
System.out.print(fibonacciSequence.fun(i)+"\t");
}
}
}
0 | 0 | 0 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|
0 | 1 | 1 | 1 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 | 0 | 0 |
0 | 1 | 1 | 0 | 1 | 0 | 0 |
0 | 1 | 1 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 1 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 |
package com.gavin.stack;
/*
* 迷宫位置对象
*/
public class MazePath {
private int x;//横坐标
private int y;//纵坐标
private int direction;//方向:1--上 2--右 3--下 4--左
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
//打印信息
public String toString() {
String direction = "";
if(this.direction == 0) {
direction += "出口";
}
if(this.direction == 1) {
direction += "向上走";
}
if(this.direction == 2) {
direction += "向右走";
}
if(this.direction == 3) {
direction += "向下走";
}
if(this.direction == 4) {
direction += "向左走";
}
return "("+this.x+","+this.y+")"+direction;
}
/**
* 重写相等比较函数
*/
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof MazePath) {
MazePath mazePath = (MazePath) obj;
return mazePath.getX() == this.x && mazePath.getY() == this.y;
}
else {
return false;
}
}
}
package com.gavin.stack;
import java.util.Stack;
/*
* 走迷宫
*/
public class Maze {
/**
* 迷宫路径栈
*/
public static Stack<MazePath> pathStack = new Stack<MazePath>();
/**
* 迷宫数组
*/
public static int[][] maze = new int[7][7];
/**
* 出口
*/
public static MazePath endMazePath = new MazePath();
/**
* 入口
*/
public static MazePath startMazePath = new MazePath();
public void initMaze() {
// 0表示障碍,1表示通路
// 创建一条通路
maze[1][1] = 1;// 起点
maze[2][1] = 1;
maze[3][1] = 1;
maze[3][2] = 1;
maze[4][2] = 1;
maze[4][3] = 1;
maze[5][3] = 1;
maze[5][4] = 1;
maze[5][5] = 1;// 终点
// 添加障碍
maze[1][2] = 1;
maze[1][3] = 1;
maze[2][3] = 1;
maze[2][4] = 1;
maze[3][4] = 1;
// 3.设置起点和终点
// 设置起点
startMazePath.setX(1);
startMazePath.setY(1);
// 设置终点
endMazePath.setX(5);
endMazePath.setY(5);
}
/**
* 打印迷宫
*
* @param maze 迷宫数组
*/
public void print(int[][] maze) {
for (int[] a : maze) {
for (int i : a) {
System.out.print(i + "\t");
}
System.out.println();
}
}
/**
* 判断当前结点是否是出口
*
* @param mazePath 当前结点
* @return 判断结果
*/
public boolean isEnd(MazePath mazePath) {
if (mazePath == null) {
return false;
} else if (mazePath.getX() == endMazePath.getX() && mazePath.getY() == endMazePath.getY()) {
return true;
}
return false;
}
/**
* 打印路径
*/
public void printPath() {
// 从下往上打印输出
for (int i = 0; i < pathStack.size(); i++) {
// 打印结点信息
System.out.println(pathStack.get(i).toString());
}
}
/**
* 判断该节点是否已经来过
*
* @param mazePath 结点
* @return 判断结果
*/
public boolean isRecord(MazePath mazePath) {
if (pathStack.size() == 0) {
return false;
} else {
return pathStack.contains(mazePath);
}
}
/**
* 递归寻找正确的路径
*
* @param mazePath 结点
*/
public void getPath(MazePath mazePath) {
// 1.先判断是否在栈中存在,如果存在结束当前递归
// 否则入栈
if (isRecord(mazePath)) {
mazePath.setDirection(0);
return;
} else {
pathStack.push(mazePath);
}
// 2.递归出口:当前结点是出口
if (isEnd(mazePath)) {
printPath();
return;
}
// 3.不是出口时,按情况递归
int x = mazePath.getX();// 横坐标
int y = mazePath.getY();// 纵坐标
MazePath newMaze = new MazePath();
// 往上走
if (maze[x - 1][y] == 1) {
// 设置方向
mazePath.setDirection(1);
// 设置新的横纵坐标
newMaze.setX(x - 1);
newMaze.setY(y);
// 递归
getPath(newMaze);
}
// 往右走
if (maze[x][y + 1] == 1) {
mazePath.setDirection(2);
newMaze.setX(x);
newMaze.setY(y + 1);
getPath(newMaze);
}
// 往下走
if (maze[x + 1][y] == 1) {
mazePath.setDirection(3);
newMaze.setX(x + 1);
newMaze.setY(y);
getPath(newMaze);
}
// 往左走
if (maze[x][y - 1] == 1) {
mazePath.setDirection(4);
newMaze.setX(x);
newMaze.setY(y - 1);
getPath(newMaze);
}
// 如果前四个方向都走不通,会执行后退
mazePath.setDirection(0);
pathStack.pop();
}
/**
* 测试函数
*
* @param args
*/
public static void main(String[] args) {
Maze mazeDemo = new Maze();
// 1.初始化故宫
mazeDemo.initMaze();
// 2.打印迷宫
mazeDemo.print(maze);
// 3.调用递归函数寻找路径
mazeDemo.getPath(startMazePath);
}
}
数据对象:
D={ai | ai∈ElemSet, i=1,2,…,n, n≥0}
数据关系:
R1={ | ai-1, ai ∈D, i=2,…,n}
约定其中,a1端为队列头,an端为队列尾
基本操作:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFzfatmK-1609764859970)(E:\StudySource\数据结构\栈和队列\图像\队列操作.png)]
package com.gavin.queue;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/*
* 先进先出
* 1.LinkedList类实现了接口Queue,所以队列的声明
* Queue queue = new LinkedList();
*
* 2.关于队列的几个常用操作:
* 2.1 boolean add(E e) 将指定的元素插入此队列(如果立即可行且不会违反容量限制),
* 在成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException。
* 2.2 boolean offer(E e) 将指定的元素插入此队列(如果立即可行且不会违反容量限制),
* 当使用有容量限制的队列时,此方法通常要优于 add(E),后者可能无法插入元素返回false
* ,而只是抛出一个异常。
* 2.3 E element() 获取,但是不移除此队列的头。
* 此方法与 peek 唯一的不同在于:此队列为空时将抛出一个异常。
* 2.4 E peek() 获取但不移除此队列的头;如果此队列为空,则返回 null。
* 2.5 E poll() 获取并移除此队列的头,如果此队列为空,则返回 null。
* 2.6 E remove() 获取并移除此队列的头。
* 此方法与 poll 唯一的不同在于:此队列为空时将抛出一个异常。
*
* 3.方法对比
* 3.1 offer,add 区别:
* 一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。
* 这时新的 offer 方法就可以起作用了。
* 它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。
*
* 3.2 poll,remove 区别:
* remove() 和 poll() 方法都是从队列中删除第一个元素。
* remove() 的行为与 Collection 接口的版本相似,
* 但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。
* 因此新的方法更适合容易出现异常条件的情况。
*
* 3.3 peek,element区别:
* element() 和 peek() 用于在队列的头部查询元素。
* 与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null。
*/
public class QueueDemo {
public static Queue<Person> queue = new LinkedList<Person>();
public static Queue<Person> queue2 = new LinkedList<Person>();
public static void main(String[] args) {
//1.boolean add(E e)
Person p1 = new Person();
p1.setAge(1);
System.out.println( queue.add(p1));
System.out.println("**********************************************");
//2.boolean offer(E e)
Person p2 = new Person();
p2.setAge(2);
System.out.println(queue.offer(p2));
System.out.println("**********************************************");
//3.E element()
System.out.println(queue.element().getAge());//1
System.out.println(queue.element().getAge());//1
//System.out.println(queue2.element());//抛出异常 java.util.NoSuchElementException
System.out.println("**********************************************");
//4.E peek()
System.out.println(queue.peek().getAge());//1
System.out.println(queue.peek().getAge());//1
System.out.println(queue2.peek());//null
System.out.println("**********************************************");
//5.E poll()
System.out.println(queue.poll().getAge());//1
System.out.println(queue.poll().getAge());//2
System.out.println(queue2.poll());//null
System.out.println("**********************************************");
//6.E remove()
queue2.offer(p1);
queue2.offer(p2);
System.out.println(queue2.remove().getAge());//1
System.out.println(queue2.remove().getAge());//2
System.out.println(queue2.remove());//抛出异常 java.util.NoSuchElementException
}
}
package com.gavin.queue;
import java.util.LinkedList;
import java.util.Queue;
/*
* 设有n个人站成一排,从左向右的编号分别为1~n,
* 现在从左向右报数“1,2,1,2,1,2….”,数到”1”的人出列,
* 数到”2”的人站到队伍最右边。报数过程反复进行,直到n个人都出列为止。
*/
public class NumberOff {
/**
* 报数队列
*/
private static Queue<NumberQueue> numberStack = new LinkedList<NumberQueue>();
/**
* 总人数
*/
private static int totalNumber = 15;
/**
* 报数
*/
public void numberOff() {
//记录当前栈中报数人数
int number = numberStack.size();
int k = 1;//标志奇数还是偶数,用于判断当前报数是1还是2
int oneTwo = 0;
//遍历队列
for(int i = 0; i < number; i++) {
//如果报数为1出列
if(numberStack.peek().getOneTwo() == 1) {
System.out.println("出列人序号:"+numberStack.poll().getNumber());
}
//否则报数为2,重新分配报数,走到队伍最右边
else {
if(k % 2 == 1) {
oneTwo = 1;
}
else {
oneTwo = 2;
}
numberStack.peek().setOneTwo(oneTwo);//重新分配报数
NumberQueue newNumberQueue = numberStack.poll();//出队列
numberStack.offer(newNumberQueue);//排到队列最右边
}
}
}
/**
* 初始化报数栈
*/
public void initStack() {
int k = 1;//标志奇数还是偶数,用于判断当前报数是1还是2
int oneTwo = 0;
for(int i = 0; i < totalNumber; i++) {
if(k % 2 == 1) {
oneTwo = 1;
}
else {
oneTwo = 2;
}
NumberQueue numberQueue = new NumberQueue(k, oneTwo);
numberStack.offer(numberQueue);
k++;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
NumberOff numberOff = new NumberOff();
numberOff.initStack();
while(numberStack.size() != 0) {
numberOff.numberOff();
}
}
}