• 栈、队列及优先级队列


    整体把握

    数组、链表、树等等都适用于数据库应用中作数据记录,常用来记录对应于现实世界的数据;而栈、队列及优先级队列更多地是作为程序员的工具来使用(用最合适的工具干活),以简化某些程序操作。

    栈、队列及优先级队列都可以使用数组链表来实现,优先级队列通常使用堆实现。

    在栈、队列及优先级队列中,访问是受限制的,在某一时刻只有某一个特定的数据项可以被读取或删除。


    应用:单词逆序;解析源代码时检验括号匹配;解析算术表达式;栈操作还嵌入在微处理器中,比如当调用一个方法时返回值和参数压入栈,方法结束时,那些数据出栈。

    解析算术表达式:

    算术表达式求值通常都是先转换为后缀表达式,再求后缀表达式的值;在中缀表表达式转换为后缀表达式以及求后缀表达式的值的过程里,栈都是很有用的工具。

    中缀表表达式 后缀表达式
    ((A+B)*C)-D AB+C*D-
    A+B*(C-D/(E+F)) ABCDEF+/-*+

     

     

     

    转换后缀表达式规则:操作数不入栈,操作符入栈,在适当的时候出栈,比如中缀表达式1+2*3-5=,解析为后缀表达式过程如下表所示

    步数 读表达式 var 栈  备注
    第一步 1 1    
    第二步 1+ 1 +  
    第三步 1+2 12 +  
    第四步 1+2* 12 +*  
    第五步 1+2*3 123 +*  
    第六步 1+2*3- 123*+ - 读到-时把*出栈,把+也出栈
    第七步 1+2*3-5 123*+5 -  
    第八步 1+2*3-5= 123*+5-   读到=时把-出栈

     

     

     

     

     

     

     

     

     

     

     

     后缀表达式求值规则:操作数入栈、遇到操作符从栈中提出两个操作数执行计算,结果入栈,计算123*+5-的值如下表所示

    步数 读表达式 栈 
    第一步 1 1
    第二步 12 12
    第三步 123 123
    第四步 123* 16
    第五步 123*+ 7
    第六步 123*+5 75
    第七步 123*+5- 2

     

     

     

     

     

     

     

     

     

     

    实现

    数组实现,栈内有一个top记录栈顶的数据顶,插入++top,删除top--
    单链表实现,push()对应insertFisrt(),pop()对应deleteFirst()

    效率

    入栈出栈O(1),也就是说,所耗的时间不依赖于栈中数据项的个数,栈不需要比较和移动操作。

    代码

    package MyTest;
    
    public class Stack {
        private int[] dataArr;
        private int initCapacity;
        private int top;
    
        public Stack(int initCapacity) {
            dataArr = new int[initCapacity];
            top = -1;
            this.initCapacity = initCapacity;
        }
    
        public void push(int element) {
            dataArr[++top] = element;
        }
    
        public int pop() {
            return dataArr[top--];
        }
    
        public int peek() {
            return dataArr[top];
        }
    
        public boolean isEmpty() {
            return top == -1;
        }
    
        public boolean isFull() {
            return top == initCapacity - 1;
        }
    }
    
    class MyTest {
        public static void main(String[] args) {
            Stack stack = new Stack(20);
            stack.push(200);
            stack.push(300);
            stack.push(404);
            stack.push(555);
            stack.push(606);
    
            System.out.print(stack.peek() + "  ");
            System.out.print(stack.peek() + "  
    ");
            while (!stack.isEmpty()) {
                int pop = stack.pop();
                System.out.print(pop + "  ");
            }
    
            if (!stack.isEmpty()) {
                System.out.print(stack.peek());
            } else {
                System.out.println();
                System.out.print("Stack is empty");
            }
        }
    }
    
    class WordReverser {
        public static void main(String[] args) {
            String str = wordReverser("中华人民共和国");
            System.out.println(str);
        }
    
        private static String wordReverser(String str) {
            Stack stack = new Stack(20);
            for (int i = 0; i < str.length(); i++) {
                stack.push(str.charAt(i));
            }
            str = "";
            while (!stack.isEmpty()) {
                str += (char) stack.pop();
            }
            return str;
        }
    }
    
    class Compiler {
        private static String src1 = "c[d]";        // correct,正确的
        private static String src2 = "a{b[c]d}e";  // correct
        private static String src3 = "a{b(c]d}e";  // not correct; doesn't match
        private static String src4 = "a[b{c}d]e}"; // not correct; nothing matches final }
        private static String src5 = "a{b(c)";     // not correct; nothing mathches opening {
        private static Stack stack = new Stack(10);
    
        public static void main(String[] args) {
            /*
             * 结果有四种情况
             * 1、正确
             * 2、不匹配
             * 3、左括号多余,右括号多余
             */
            compile(src5);
        }
    
        public static void compile(String src) {
            char c = 0;
            for (int i = 0; i < src.length(); i++) {
                c = src.charAt(i);
                switch (c) {
                    case '{':
                    case '[':
                    case '(':
                        stack.push(c);
                        break;
                    case '}':
                    case ']':
                    case ')':
                        if (stack.isEmpty()) {
                            System.out.println("not correct; nothing matches final " + (char)c);
                            return;
                        } else {
                            int pop = stack.pop();
                            if (!(pop == '{' && c == '}' || pop == '[' && c == ']' || pop == '(' && c == ')')) {
                                System.out.println("not correct; doesn't match");
                                return;
                            }
                        }
                }
            }
            if (stack.isEmpty()) {
                System.out.println("correct");
            } else {
                System.out.println("not correct; nothing mathches opening " + (char) stack.pop());
            }
        }
    }
    View Code

    队列

    应用

    因特网数据包等待传送;操作系统里有很多队列,打印作业的打印队列;文字处理软件有一个容纳键入内容的队列,队列保证了键入内容的顺序不会改变。
    队列也可以用于模拟真实世界,比如模拟银行排队、飞机等待起飞。

    实现

    数组实现,通常的作法是通过移动队头队尾的指针保持数据项的位置不变,这样必须使用环绕式处理。
    双端链表实现,insert()对应insertLast(),remove对应deleteFirst()

    效率

    插入删除数据项的时间复杂度都是O(1)


    双端队列

    头尾都可以插入和删除,比如可能有方法insertLeft()/insertRight、removeLeft()/removeRight()


    优先级队列 

    优先级队列其实就是有序队列,有升序优先级队列和降序优先级队列;它允许访问最小(最大)的数据项。

    应用

    在抢先式多任务操作系统中,程序排列在优先级队列中,这样优先级最高的程序就会先得到时间片运行。
    很多情况下需要访问具有最小关键字值的数据项,比如寻找最便宜的方法或最短的路径去做某件事。

    实现

    除了可以快速访问最小关键字值的数据项,优先级队列还应该实现相当快的插入数据项,因此优先级队列通常使用椎来实现。
    数组实现1——>有序数组实现,不需要使用环绕指针,插入慢,删除快
    数组实现2——>无序数组实现,插入快,删除慢,因为要寻找最小值
    有序链表实现

  • 相关阅读:
    删除maven本地库中下载不完全的jar包
    nginx负载均衡
    对字符串中的中英文进行统计
    springboot部分常用注解
    Scala 泛型
    Scala 递归举例
    Kafka(v0.11)笔记
    Scala 匿名函数与参数类型推断(简写)
    Scala 高阶函数
    Scala 偏函数 PartialFunction
  • 原文地址:https://www.cnblogs.com/Mike_Chang/p/10201225.html
Copyright © 2020-2023  润新知