【数据结构】栈与队列(二)

简介: 栈与队列

3.5 栈的应用


3.5.1 大数加法


p76

9992992347234947324732498327427342472987427427984724274

+

  9990920943824283492834824820984028348204209384029293

  • 思路:9293 + 978

image.png

3.5.2 后缀表达式


p79

  • 中序表达式:日常生活中编写的都是中序表达式。

a + b - c

后缀表达式:把运算符写在后面的表达式,也称为逆波兰记法

中序:a+b              后缀:ab+

中序:a + b - c        后缀:ab+c-

中序:a + b * c        后缀:abc*+

  • 除运算符之外的内容,依次填写
  • 使用一个栈记录运算符
  • 入栈:新入栈的运算符比栈里的运算符优先级要高。如果是(进行入栈操作
  • 出栈:新入栈的运算符没有栈里的运算符优先级高,栈里的运算符需要出栈,新运算符入栈。如果是)出栈直到(

将以下中序表达式转换成后续表达式

中序:8-(3+2*6)/5+2^2          后缀:8326*+5/-22^+

中序:2*9+3-2*(10-3)/14        后缀:29*3+2103-*14/-

中序:A+B*(C*D-E)              后缀:ABCD*E-*+

中序:a+b*c+(d*e+f)*g          后缀:abc*+de*f+g*+

中序:9+(3-1)*3+10/2           后缀:931-3*+102/+

3.5.3 汉诺塔 Hanoi


  • 游戏规则 (P84)

共3个柱子,在一根柱子上,从下往上按照大小顺序摞着N片圆盘。把圆盘开始按大小顺序重新摆放在另一根柱子上

规定:在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

算法:

packagehanoi;
/*** @author 桐叔* @email liangtong@itcast.cn*/publicclassTestHanoi {
privatestaticintcount=0;
/**** @param n 需要移动的盘子数* @param x 第一个柱子 起始* @param y 第二个柱子 过渡* @param z 第三个柱子 最后*/publicstaticvoidhanoi(intn, charx, chary , charz) {
if(n==1) {      //只有一个盘子move(x, 1, z);
        } else {
hanoi(n-1, x, z ,y);     // n上面的盘子,从x柱子,通过z柱子,移动到y柱子move(x, n, z);              //n盘子,从x柱子,移动到z柱子hanoi(n-1, y, x, z);    // n上面的盘子目前在y柱子,从y柱子,通过x柱子,移动到z柱子。        }
    }
/**** @param x 第一个柱子* @param n 需要移动的盘子号* @param z 第三个柱子*/privatestaticvoidmove(charx, intn, charz) {
count++;
System.out.println("第"+count+"次移动"+n+"号盘子,从"+x+"柱子到"+z+"柱子");
    }
publicstaticvoidmain(String[] args) {
hanoi(4,'x','y','z');
    }
}

3.6 队列


3.6.1 定义


  • 队列是一个特殊的线性表。
  • 只允许在表尾进行插入操作
  • 只允许在表头进行删除操作
  • 队列操作特点:
  • 先进先出(FIFO,First In First Out)
  • or 后进后出(LILO,Last In Last Out)
  • 术语:
  • 队尾rear:进行插入操作的一端。
  • 队首front:进行删除操作的一端。
  • 入队offer:进行插入操作,称为入队。
  • 出队poll:进行删除操作,称为出队。

image.png

  • 队列两种存储结果分类:
  • 使用顺序存储的称为顺序队列
  • 使用链式存储称为链队列。

3.7 顺序队列


3.7.1 顺序队列


  • 顺序队列的存储结构中,需要分配一块地址连续的存储区域来一次存放队列中从队首到队尾的所有元素。
  • 操作总结:
  • front表示队首,进行出队操作时,front进行计数。
  • rear表示队尾,进行入队操作时,rear进行计数。
  • front == rear == 0 空队列。
  • 操作步骤:
  • 入队操作:

image.png

image.png

image.png

image.png

3.7.2 循环顺序队列


  • 循环顺序队列:就是在逻辑上队首和队尾连接在一起。
  • 存在问题:队首front和队尾rear重叠时,无法表示队列是满了,还是空的。
  • 解决方案:
  • 方案1:设计一个计数器(整数变量num,入队+1,出队-1,如果num=0就是空)
  • 方案2:设计一个标识变量(flag=0出队,flag=1入队,重叠后0表示空,1表示满)
  • 方案3:少用一个存储单位

image.png

// 队列空front==rear;
// 队列满(rear+1) %maxSize==front;
//余数操作5%5=0;
2%5=2;  

3.7.3 循环顺序队列类


  • 循环顺序队列,在逻辑上是一个循环,也就是队首和队尾连接。

    image.png

image.png

publicClassCircleQueue {
privateObject[] queueElem;     //物理数组privateintfront;              //队首privateintrear;               //队尾}

3.7.4 算法:循环顺序队列入队【重点】


publicvoidoffer(Objectx) {
if( (rear+1) %queueElem.length==front ) {  // 1.判断,如果已经满了,抛异常thrownewRuntimeException('队列满了');
    } else {
queueElme[ rear ] =x;                   // 2.没有满进行入队操作rear= (rear+1) %queueElem.length;    // 3.队尾rear累加1,但最后时需要归零    }
}

3.7.5 算法:循环顺序队列出队【重点】


image.png

publicObjectpoll() {
if( front==rear ) {                       // 判断 空 返回nullreturnnull;
    } 
Objectdata=queueElem[front];             // 如果不为空,获得队首front元素front= (front+1) %queueElem.length;     // 队首+1,且需要归零  returndata;
}
相关文章
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
546 1
|
10月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
218 0
栈区的非法访问导致的死循环(x64)
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
884 77
|
10月前
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
529 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
算法 调度 C++
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
339 11
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
430 7
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
1201 10
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
389 59