【数据结构真不难】栈与队列——五一专属|向所有热爱分享的“技术劳动者”致敬(二)

简介: 【数据结构真不难】栈与队列——五一专属|向所有热爱分享的“技术劳动者”致敬(二)

5.栈的应用


5.1大数加法


9992992347234947324732498327427342472987427427984724274

+

  9990920943824283492834824820984028348204209384029293


思路:9293 + 978微信图片_20220530210244.png

5.2后缀表达式


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


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/+


5.3汉诺塔Hanoi


游戏规则


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

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


算法

package hanoi;
public class TestHanoi {
    private static int count = 0;
    /**
     *
     * @param n 需要移动的盘子数
     * @param x 第一个柱子 起始
     * @param y 第二个柱子 过渡
     * @param z 第三个柱子 最后
     */
    public static void hanoi(int n, char x, char y , char z) {
        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 第三个柱子
     */
    private static void move(char x, int n, char z) {
        count++;
        System.out.println("第"+count+"次移动"+n+"号盘子,从"+x+"柱子到"+z+"柱子");
    }
    public static void main(String[] args) {
        hanoi(4,'x','y','z');
    }
}

6.队列


6.1定义


队列是一个特殊的线性表。


只允许在表尾进行插入操作


只允许在表头进行删除操作


队列操作特点:


先进先出(FIFO,First In First Out)


or 后进后出(LILO,Last In Last Out)


术语:


队尾rear:进行插入操作的一端。


队首front:进行删除操作的一端。


入队offer:进行插入操作,称为入队。


出队poll:进行删除操作,称为出队。微信图片_20220530210444.png


队列两种存储结果分类:


* 使用顺序存储的称为顺序队列

* 使用链式存储称为链队列。


7.顺序队列


7.1顺序队列


顺序队列的存储结构中,需要分配一块地址连续的存储区域来一次存放队列中从队首到队尾的所有元素。


操作总结:


front表示队首,进行出队操作时,front进行计数。


rear表示队尾,进行入队操作时,rear进行计数。


front == rear == 0 空队列。


操作步骤:


入队操作:微信图片_20220530210451.png

出队操作

微信图片_20220530210656.png

存在问题:假溢出,数组的最后一个元素已经添加数据,但队列没有满。

微信图片_20220530210810.png

解决方案:使用循环顺序队列解决“假溢出”问题。微信图片_20220530210855.png

7.2循环顺序队列


循环顺序队列:就是在逻辑上队首和队尾连接在一起。


存在问题:队首front和队尾rear重叠时,无法表示队列是满了,还是空的。


解决方案:


方案1:设计一个计数器(整数变量num,入队+1,出队-1,如果num=0就是空)


方案2:设计一个标识变量(flag=0出队,flag=1入队,重叠后0表示空,1表示满)



方案3:少用一个存储单位微信图片_20220530210900.png

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

 7.3循环顺序队列类


循环顺序队列,在逻辑上是一个循环,也就是队首和队尾连接。微信图片_20220530210906.png

循环顺序队列,物理上就是一个数组。微信图片_20220530210911.png

public Class CircleQueue {
    private Object[] queueElem;  //物理数组
    private int front;    //队首
    private int rear;    //队尾
}


/

 7.4算法:循环顺序队列入队


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

 

7.5算法:循环顺序队列出队微信图片_20220530210918.png


public Object poll() {
    if( front == rear ) {           // 判断 空 返回null
        return null;
    } 
    Object data = queueElem[front];       // 如果不为空,获得队首front元素
    front = (front + 1) % queueElem.length;   // 队首+1,且需要归零  
    return data;
}


相关文章
|
21小时前
|
存储 测试技术
【数据结构】操作受限的线性表,栈的具体实现
【数据结构】操作受限的线性表,栈的具体实现
11 5
|
21小时前
|
存储 测试技术
【数据结构】操作受限的线性表,队列的具体实现
【数据结构】操作受限的线性表,队列的具体实现
10 4
|
1天前
|
算法
【C/数据结构和算法】:栈和队列
【C/数据结构和算法】:栈和队列
6 1
|
17小时前
|
存储 算法
【数据结构和算法】--队列的特殊结构-循环队列
【数据结构和算法】--队列的特殊结构-循环队列
4 0
|
17小时前
|
算法
【数据结构和算法】--队列
【数据结构和算法】--队列
4 0
|
4天前
|
缓存 调度
栈和队列的区别
栈和队列的区别
8 0
|
5天前
|
算法 Java 编译器
Java数据结构与算法:线性数据结构之栈
Java数据结构与算法:线性数据结构之栈
|
5天前
|
存储 程序员 编译器
堆和栈的区别
堆和栈的区别
|
11天前
数据结构——栈和队列
数据结构——栈和队列
13 1
|
14天前
|
存储 算法 调度
数据结构与算法-栈篇
数据结构与算法-栈篇
14 3