算法 背包队列和栈

Posted tenwood

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法 背包队列和栈相关的知识,希望对你有一定的参考价值。

许多基础数据类型都和对象的集合有关。具体来说,数据类型的值就是一组对象的集合,所有操作都是关于添加、删除或是访问集合中的对象。在本节中,我们将学习三种这样的数据类型,分别是背包(Bag)、队列(Queue)、和栈(Stack). 他们的不同之处在于删除或者访问对象的顺序不同。

一、背包

API:

public class Bag<Item> implements Iterable<Item>
Bag()                        创建一个空背包
void add(Item item)            添加一个元素
boolean isEmpty()            背包是否为空
int size()                    背包中的元素数量

背包一种不支持从中删除元素的集合数据类型。迭代的顺序不确定且与用例无关。

 

二、先进先出队列

在应用程序中使用队列的主要原因是在用集合保存元素的同时保存它们的相对顺序:使他们入列顺序和出列顺序相同。

API:

public class Queue<Item> implements Iterable<Item>
Queue()                        创建空队列
void enqueue(Item item)        添加一个元素
Item dequeue()                删除最近添加的元素
boolean isEmpty()            队列是否为空
int size()                    队列中的元素数量

 

三、下压栈

下压栈(或简称栈)是一种基于后进先出策略的集合类型;当用例使用foreach语句迭代遍历栈中的元素时,元素的处理顺序和它们被压入的顺序正好相反。
在应用程序中使用栈迭代器的一个典型原因是在用集合保存元素的同时颠倒它们的相对顺序。

API:

public class Stack<Item> implements Iterable<Item>
Stack()                        创建一个空栈
void push(Item item)        添加一个元素
Item pop()                    删除最近添加的元素
boolean isEmpty()            栈是否为空
int size()                    栈中的元素数量

一个栈例子,计算( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 

如何使用程序来完成计算呢?
大神发明了一个非常简单的算法,用两个栈(一个用于保存运算符,一个用于保存操作数)完成了这个任务。
表达式由括号、运算符和操作数(数字)组成。我们根据以下4种情况从左到右逐个将这些实体送入栈处理:
.将操作数压入操作数栈;
.将运算符压入运算符栈;
.忽略左括号;
.在遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈。(p91)

代码:

技术分享图片
package algorithm;

import stdLib.StdIn;
import stdLib.StdOut;

/**
 * 〈Dijkstra的双栈算术表达式求值算法〉<br>
 */
public class Evaluate {

    public static void main(String[] args) {
        Stack<String> ops = new Stack<>();
        Stack<Double> vals = new Stack<>();
        while (!StdIn.isEmpty()) {
            // 读取字符,如果是运算符则压入栈
            String s = StdIn.readString();

            if(s.equals("end")){
                System.out.println(vals.pop());
                break;
            }

            if (s.equals("("))                 ;
            else if (s.equals("+")) ops.push(s);
            else if (s.equals("-")) ops.push(s);
            else if (s.equals("*")) ops.push(s);
            else if (s.equals("/")) ops.push(s);
            else if (s.equals("sqrt")) ops.push(s);
            else if (s.equals(")")){
                //如果字符为")",弹出运算符和操作数,计算结果并压入栈
                String op = ops.pop();
                double v = vals.pop();
                if(op.equals("+")) v = vals.pop() + v;
                else if(op.equals("-")) v = vals.pop() - v;
                else if(op.equals("*")) v = vals.pop() * v;
                else if(op.equals("/")) v = vals.pop() / v;
                else if(op.equals("sqrt")) v = Math.sqrt(v);
                vals.push(v);
            }//如果字符既非运算符也不是括号,将它作为double值压入栈
            else vals.push(Double.parseDouble(s));
        }
    }
}
View Code

console输入计算表达式,输入end结束:

( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) )

end
101.0

 








以上是关于算法 背包队列和栈的主要内容,如果未能解决你的问题,请参考以下文章

数据结构(背包队列和栈)

C语言算法系列---1.队列和栈

书籍-算法

队列和栈------《啊哈!算法》

算法系列数据结构之表队列和栈

数据结构与算法 ----- 队列