15.第20章:线性表、栈、队列、优先队列

java框架支持两种类型的容器:

  • 为了存储一个元素集合,简称合集
  • 为了存储键/值对,称为映射表

1.集合

  • Set用于存储一组不重复的元素
  • List用于存储一个有序元素集合
  • Stack用于存储后进先出方式处理的对象
  • Queue用于存储采用先进先出方式处理的对象
  • Priority Queue用于存储按照优先级顺序处理的对象


collection接口:

collection接口

2.迭代器

Iterator是一种经典的设计模式,用于在不需要暴露数据是如何保存在数据结构的细节的情况下,来遍历一个数据结构。
Collection接口继承自Iterator接口,Iterator接口中Iterator()方法返回一个Iterator的实例。



3.线性表 List

List接口继承自Collection接口,定义了一个用于顺序存储元素的集合。可以使用ArrayList(数组线性表)和LinkedList(链表)来创建一个线性表。

  • List接口通用方法

方法listIterator()会返回ListIterator的一个实例。ListIterator接口继承了Iterator接口,以增加对线性表的双向遍历能力。


ListIterator接口可以双向遍历线性表
  • 数组线性表类ArrayList和链表类LinkedList

ArrayList和LinkedList是实现List接口的两个具体类。
1)ArrayList
ArrayList用数组存储元素,这个数组是动态创建的。如果元素个数超过了数组的容量,就创建一个更大的新数组,并将当前数组中所有元素都复制到新数组中。



2)LinkedList
LinkedList在一个链表中存储元素。



比较:
如果需要通过下标随机访问元素,而不会在线性表起始末尾位置插入或删除,使用ArrayList效率高。
如果需要在线性表起始末尾位置插入删除元素,选用LinkedList效率高。
public class text1_线性表 {
    public static void main(String[] args ){
        //ArrayList
        List<Integer> arrayList=new ArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(0,10);
        arrayList.add(3,30);
        System.out.println(arrayList);




        //linkedList
        LinkedList<Object> linkedList=new LinkedList();
        linkedList.add("red");
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        linkedList.addFirst("yellow");
        linkedList.removeLast();
        System.out.println(linkedList);
        //从前向后遍历
        ListIterator listIterator=linkedList.listIterator();
        while (listIterator.hasNext()){
            System.out.print(listIterator.next()+" ");
        }
        System.out.println();
        //从后向前遍历
        listIterator=linkedList.listIterator(linkedList.size());
        while (listIterator.hasPrevious()){
            System.out.print(listIterator.previous()+" ");
        }
    }
}


4.Collections类

Collections类包含了执行合集和线性表中通用操作的静态方法。


5.Vector和栈

  • Vector

Vector是AbstractList的子类,Stack是Vector的子类。
Vector是同步的,如果不需要同步,建议使用ArrayList效率高


图片.png
  • stack类

6.队列和优先队列

  • 队列(queue)是一种先进先出的数据结构。元素被追加到队列末尾,然后从队列头部出去。


  • 双端队列(Deque),继承自Queue接口,增加了如下方法:addFirst(e)、removeFirst()、addLast(e)、removeLast()、getFirst()和getLast()这些从队列两端插入和删除的方法。
  • 可以使用LinkedList创建一个队列。
public class text2_队列 {
    public static void main(String[] args){
        //LinkedList实现了List和Deque接口,Deque接口继承了Queue接口,使用LinkedList()创建队列
        Queue queue=new LinkedList();
        queue.offer("hello");
        queue.offer("Queue");
        queue.offer("Deque");
        while (queue.size()>0){
            System.out.print(queue.remove()+" ");
        }
    }
}
  • 优先队列PriorityQueue



    优先队列默认字符串以升序从队列删除


    图片.png

7.示例:算数表达式求值

分析:
准备两个栈,一个用于准备放符号operatorStack,一个用于准备放数字operandStack。
准备:为得到的字符串表达式的()+-/左右两边添加空格,方便将多位数区分出来。以空格隔开。
1)如果遇到的是数字,将其push到operandStack中
2)如果遇到的符号是+或-:
operatorStack不为空,并且栈顶元素是+-
/,循环pop得到操作符,同时operandStack弹出两个操作数,将计算结果push进operandStack。直到 operatorStack为空
operatorStack为空,直接将操作符push进operatorStack。
3)如果遇到的是或/,栈顶元素是/,就弹出计算,循环直到operatorStack为空。
operatorStack为空,直接将操作符push进operatorStack。
4)如果遇到的是(,直接压入符号栈;
如果遇到),取出操作符计算,直到栈顶元素是(,最后弹出(。
5)如果 operatorStack不为空,就循环,弹出 operatorStack操作符,弹出operandStack中两个数据,计算结果push进operandStack。
6)返回operandStack的值就是结果

public class text3_算数表达式求值 {
    public static void main(String[] args){
        System.out.println("输入算数表达式");
        Scanner input=new Scanner(System.in);
        String caculate=input.nextLine();
        try {
            System.out.println(evaluateExpression(caculate));
        }catch (Exception e){
            System.out.println("Wrong expression");
        }

    }

    private static Double evaluateExpression(String caculate) {
        //定义了操作符的栈
        Stack<Character> operatorStack=new Stack();
        //定义了操作数的栈
        Stack<Double> operandStack=new Stack();
        //需要在所有符号前后加上空格,来分割数字,多位数才能正确读取
        caculate=insertBlanks(caculate);
        String[] tokens=caculate.split(" ");
        for(String token:tokens){
            //分割后token,第一个是空格,可能分割后是第一个是空串
            if(token.length()==0)
                continue;
            //如果遇到的是+ -
            if(token.charAt(0)=='+'||token.charAt(0)=='-'){
                while(!operatorStack.isEmpty()&&(operatorStack.peek()=='+'||operatorStack.peek()=='-'||operatorStack.peek()=='*'||operatorStack.peek()=='/')){
                    processAnOperator(operandStack,operatorStack);
                }
                operatorStack.push(token.charAt(0));
            }
            //如果遇到的是* /
            else if(token.charAt(0)=='*'||token.charAt(0)=='/'){
                while (!operatorStack.isEmpty()&&(operatorStack.peek()=='*'||operatorStack.peek()=='/')){
                    processAnOperator(operandStack,operatorStack);
                }
                operatorStack.push(token.charAt(0));
            }
            //如果是(
            else if(token.charAt(0)=='('){
                operatorStack.push(token.charAt(0));
            }
            //如果是)
            else if(token.charAt(0)==')'){
                while (operatorStack.peek()!='('){
                    processAnOperator(operandStack,operatorStack);
                }
                operatorStack.pop();//把(弹出
            }
            //是数字
            else{

               operandStack.push(new Double(token));
            }
        }

        while (!operatorStack.isEmpty()){
            processAnOperator(operandStack,operatorStack);
        }

       //返回最后在数字栈內的值就是结果
        return operandStack.pop();


    }

    private static String insertBlanks(String caculate) {
        String result="";
        for(int i=0;i<caculate.length();i++)
        {
            if(caculate.charAt(i)=='('||caculate.charAt(i)==')'||caculate.charAt(i)=='+'||caculate.charAt(i)=='-'
                    ||caculate.charAt(i)=='*'||caculate.charAt(i)=='/')
                result+=" "+caculate.charAt(i)+" ";
            else
                result+=caculate.charAt(i);
        }
        return result;
    }

    private static void processAnOperator(Stack<Double> operandStack, Stack<Character> operatorStack) {
        char op=operatorStack.pop();
        double num2=operandStack.pop();
        double num1=operandStack.pop();
        switch (op){
            case '+':operandStack.push(num1+num2);break;
            case '-':operandStack.push(num1-num2);break;
            case '*':operandStack.push(num1*num2);break;
            case '/':operandStack.push(num1/num2);break;
        }

    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 栈 栈的英文单词是Stack,它代表一种特殊的线性表,这种线性表只能在固定一端(通常认为是线性表的尾端)进行插入,...
    Jack921阅读 1,481评论 0 5
  • 数据结构是编程的起点,理解数据结构可以从三方面入手: 逻辑结构。逻辑结构是指数据元素之间的逻辑关系,可分为线性结构...
    yhthu阅读 2,260评论 0 6
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,493评论 18 399
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,471评论 0 3
  • 巨婴,求你快快长大 2016年热词 ---巨婴 于是我搜索了一下:心理滞留在...
    haihailo阅读 257评论 0 2