zoukankan      html  css  js  c++  java
  • javascript中的队列结构

    1.概念

      队列和栈结构不同,栈是一种后进先出的结构,而队列是一种先进先出的结构。队列也是一种表结构,不同的是队列只能在队尾插入元素,在队首删除元素,可以将队列想象成一个在超时等待排队付钱的队伍,或者在银行拿的号子,排在前面的人拥有优先服务权。队列是一种FIFO(First In First Out)。队列用在很多地方,比如提交操作系统执行一系列的进程,打印任务池等,一些仿真系统使用队列来模拟银行或者超时里排队的顾客。

      队列主要有两种操作,祥队列中插入新元素和删除队列中的元素。插入操作也叫入队,删除操作也叫出队。入队操作在队尾插入新元素,出队操作删除队头的元素。队列的应外一项重要操作是读取队头的元素,这个操作叫做peek(),这个操作返回对头元素,并不删除它。除了读取对头元素我们还想知道队列中存储了多少元素,可以使用length属性满足该要求,想要清空队列中的所有元素,可以使用clear()方法来实现。

      使用数组来实现队列看起来顺理成章,javascript中的数组有其他编程语言中没有的有点,数组使用push()方法可以在数组的末尾加入元素,使用shift()方法可以删除数组的第一个元素。push()方法将它的参数插入数组中第一个开放的位置,该位置总在数组的末尾,即使是一个空数组也是。就是说push()插入的元素总是数组的最有一个元素。看下面的例子:  

    names = [];
    name.push("Cynthia");
    names.push("Jennifer");

    现在数组中的第一个元素是Cynthia,第二个元素是Jennifer。

      使用shift()方法删除数组的第一个元素。

    2.实现

      下面看看队列的实现方法:

    /*--------------Queue类的定义和测试代码----------------*/
    function Queue(){
            this.dataStore = [];
            this.enqueue = enqueue;
            this.dequeue = dequeue;
            this.front = front;
            this.back = back;
            this.toString = toString;
            this.empty = empty;
    }
    
    //入队,就是在数组的末尾添加一个元素
    function enqueue(element){
        this.dataStore.push(element);
    }
    //出队,就是删除数组的第一个元素
    function dequeue(){
        return this.dataStore.shift();
    }
    //取出数组的第一个元素
    function front(){
        return this.dataStore[0];
    }
    //取出数组的最后一个元素
    function back(){
        return this.dataStore[this.dataStore.length-1];
    }
    
    function toString(){
        var retStr = "";
        for (var i=0; i<this.dataStore.length; ++i) {
            retStr += this.dataStore[i] + "&nbsp;"
        }
        return retStr;
    }
    //判断数组是否为空
    function empty(){
        if(this.dataStore.length == 0){
            return true;
        }else{
            return false;
        }    
    }
    //返回数组中元素的个数
    function count(){
        return this.dataStore.length;
    }
    
    var q = new Queue();
    q.enqueue("Meredith");
    q.enqueue("Cynthia");
    q.enqueue("Jennifer");
    document.write(q.toString());
    document.write('<br>');
    document.write("Front of queue is:" + q.front());
    document.write('<br>');
    document.write("Back of queue is:" + q.back());

    最后的输出结果为:

    3.使用队列实现基数排序

    队列不仅用于执行现实生活中关于队列相关的操作,还可以用于对数据进行排序。计算机刚刚出现的时候,程序是通过穿孔输入主机的,每一张卡包含一条程序语句。这些穿孔卡装在一个盒子里面,经过一个机械装置进行排序。我们可以用一组队列来模拟这个过程。这种排序技术叫做基数排序

    对于0~99的数字,基数排序将数据集扫描两次。第一次按照个位上的数字进行排序,第二次按照十位上的数字进行排序。每个数组根据对应位上的数字被分配在不同的盒子里。

    举例如下:假如有数字 91,46,85,15,92,35,31,22
    经过基数排序第一次扫描之后按照个位数的大小排序,数字被分配大如下的盒子中
    第0个盒子:
    第1个盒子:91,31
    第2个盒子:92,22
    第3个盒子:
    第4个盒子:
    第5个盒子:85,15,35
    第6个盒子:46
    第7个盒子:
    第8个盒子:
    第9个盒子:

    根据盒子的顺序,对数字经行第一次排序的结果如下:
    91,31,92,22,85,15,35,46

    然后根据十位上的数值再将上次排序结果分配到不同的盒子里
    第0个盒子:
    第1个盒子:15
    第2个盒子:22
    第3个盒子:31,35
    第4个盒子:46
    第5个盒子:
    第6个盒子:
    第7个盒子:
    第8个盒子:85
    第9个盒子:92,92

    最后将盒子里的数字取出,组成一个新的列表,该列表即为排好顺序的数字:
    15,22,31,35,46,85,91,92

    使用队列代表盒子,可以实现这个算法,我们需要9个队列,每个对应一个数字。将所有队列保存在一个数组中,使用取余和出发操作决定各位和十位。算法的剩余部分将数字加入对应的队列,根据个位数值重新排序,然后再根据十位数值经行排序,结果即为排好顺序的数字。

    下面我们来看代码实现:

    /*--------------Queue类的定义和测试代码----------------*/
    function Queue(){
            this.dataStore = [];
            this.enqueue = enqueue;
            this.dequeue = dequeue;
            this.front = front;
            this.back = back;
            this.toString = toString;
            this.empty = empty;
    }
    
    //入队,就是在数组的末尾添加一个元素
    function enqueue(element){
        this.dataStore.push(element);
    }
    //出队,就是删除数组的第一个元素
    function dequeue(){
        return this.dataStore.shift();
    }
    //取出数组的第一个元素
    function front(){
        return this.dataStore[0];
    }
    //取出数组的最后一个元素
    function back(){
        return this.dataStore[this.dataStore.length-1];
    }
    
    function toString(){
        var retStr = "";
        for (var i=0; i<this.dataStore.length; ++i) {
            retStr += this.dataStore[i] + "&nbsp;"
        }
        return retStr;
    }
    //判断数组是否为空
    function empty(){
        if(this.dataStore.length == 0){
            return true;
        }else{
            return false;
        }    
    }
    //返回数组中元素的个数
    function count(){
        return this.dataStore.length;
    }
    
    /*----------------基数排序-----------------*/
    document.write('<br><br>');
    function distribute(nums,queues,n,digit){
        for (var i=0; i<n; ++i) {
            if(digit == 1){
                //各位数字入队
                queues[nums[i]%10].enqueue(nums[i]);
            }else{
                //十位数字入队
                queues[Math.floor(nums[i] / 10)].enqueue(nums[i]);
            }
        }    
    }
    
    //收集队列中的数字放在数字nums中
    function collect(queues,nums){
        var i=0;
        for (var digit=0; digit<10; ++digit) {
            while (!queues[digit].empty()){
                nums[i++] = queues[digit].dequeue();
            }
        }
    }
    
    function dispArray(arr){
        for (var i=0; i<arr.length; ++i) {
            document.write(arr[i] + "&nbsp;");
        }
    }
    
    //初始化9个队列
    var queues = [];
    for (var i=0; i<10; i++) {
        queues[i] = new Queue();
    }
    //初始化10个二位整数
    var nums = [];
    for (var i=0; i<10; ++i) {
        nums[i] = Math.floor(Math.random()*100);
    }
    
    document.write('排序之前');document.write('<br>');
    dispArray(nums);
    document.write('<br>');
    //按照个位数字入相应的队列
    distribute(nums, queues, 10, 1);
    //收集队列中的数字放在数组nums中
    collect(queues, nums);
    //按照十位数字如相应的队列
    distribute(nums, queues, 10, 10);
    //手机队列中的数字放在nums中
    collect(queues, nums);
    document.write("排序之后");document.write('<br>');
    dispArray(nums);

    输出结果如下:

  • 相关阅读:
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 88怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 81.0怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 40怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 24.0怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 21.0怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下驱动器试运行提示过速度保护怎么办
    倍福TwinCAT(贝福Beckhoff)基础教程 松下驱动器如何执行绝对值清零
    倍福TwinCAT(贝福Beckhoff)基础教程 松下绝对值驱动器如何做初始化设置
    倍福TwinCAT(贝福Beckhoff)基础教程 松下官方软件开启报错伺服未就绪怎么办
    JAVA Eclipse 启动 Eclipse 弹出“Failed to load the JNI shared library jvm_dll”怎么办
  • 原文地址:https://www.cnblogs.com/tylerdonet/p/5837730.html
Copyright © 2011-2022 走看看