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

 

輸出結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM