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);

    输出结果如下:

  • 相关阅读:
    CSS——如何清除浮动
    CSS——display(Block none inline等)属性的用法
    css3——position定位详解
    [转载]mysql创建临时表,将查询结果插入已有表中
    [转载]基于LVS的AAA负载均衡架构实践
    Percona Toolkit 2.2.19 is now available
    [转载]使用awk进行数字计算,保留指定位小数
    [转载]github在线更改mysql表结构工具gh-ost
    [转载]binlog归档
    [转载]MySQL运行状态show status详解
  • 原文地址:https://www.cnblogs.com/tylerdonet/p/5837730.html
Copyright © 2011-2022 走看看