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] + " " } 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] + " " } 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] + " "); } } //初始化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);
輸出結果如下: