JavaScript中的數據結構及實戰系列(1):隊列

開題

張三丰教無忌太極劍法:
        還記得嗎?
        全都記得.
        如今呢?
        已經忘卻了一小半.
        啊,已經忘了一大半.
        不壞不壞,忘得真快,那麼如今呢?
        已經全都忘了,忘得乾乾淨淨.
        好了,你上吧.

長時間寫前端代碼,將本身之前的積累都忘得一乾二淨,因此開了一個關於JS的數據結構系列,在業務型程序員的基礎上,也要實時的優化本身的代碼,讓本身的代碼有思想是每一個程序員最自豪的事情。html

本文目錄前端

隊列介紹:

相信任何有些編程基礎的人都對隊列不算陌生,隊列是一種先進先出的接口,也就是FIFO(First Input First Output),它也是一種表結構。在隊列的隊尾插入數據,在隊首刪除數據,能夠想象成咱們天天早晨買豆漿時隊伍。程序員

隊列只要有兩個主要的功能:出隊(push)和入隊(pop)。入隊操做在隊尾插入新的元素,出隊操做返回並刪除隊首的元素。有時候咱們只須要獲取隊首和隊尾但並不必定非要執行隊列的出隊和入隊行爲,因此咱們又須要一個獲取隊首(getFirst)和隊尾(getLast)的行爲。有時咱們也有所有清空本隊列的動做,因此還要有clear方法。除了以上提到的咱們還須要知道隊列中有多少個元素,能夠用length去獲取。算法

JavaScript實現:

使用數組的push方法和shift方法能夠基本完成隊列的出隊和入隊操做,可是咱們爲了避免讓其餘無關的數組屬性去破壞隊列結構還須要對其封裝一下,因此就有了咱們如今的代碼:編程

function Queue(){
    var items = [];
    //入隊
    this.push = function(obj){
        items.push(obj);
    };

    //出隊
    this.pop = function(){
        return items.shift(); 
    };

    //獲取隊首
    this.getFirst = function(){
        return items[0];
    };

    //獲取隊尾
    this.getLast = function(){
        return items[items.length-1];
    };

    //清空本隊列
    this.clear = function(){
        items = [];
    }

    //獲取隊列指定位置
    this.get = function(k){
        return items[k];
    };

    //獲取隊列長度
    this.length = function(){
        return items.length;
    };

    //隊列是否爲空
    this.empty = function(){
        return items.length === 0;
    };
}

var lazyQueue = new Queue();

lazyQueue.push({
    a: 1, 
    b: 2
});

lazyQueue.push({
    c: 3, 
    d: 4
});

console.log(lazyQueue.pop());
console.log(lazyQueue.length());
console.log(lazyQueue.clear());
console.log(lazyQueue.pop());
console.log(lazyQueue.length());

輸出結果爲:數組

{a: 1, b: 2}
1
undefined
undefined
0

隊列的實踐:

在咱們的開發遇到不少隊列的使用,且隊列的應用也比較簡單,只要在執行完上次任務後再執行本任務,直到隊列爲空爲止。數據結構

以前分享了PHP以及JavaScript的八大排序方式,可是對於基數排序的JavaScript實現方法沒有搞清楚,如今能夠補上了。dom

首先將「基數排序」的概念理解一下: 基數排序(radix sort)屬於「分配式排序」(distribution sort),又稱「桶子法」(bucket sort)或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些「桶」中,藉以達到排序的做用,基數排序法是屬於穩定性的排序,其時間複雜度爲O (nlog(r)m),其中r爲所採起的基數,而m爲堆數,在某些時候,基數排序法的效率高於其它的穩定性排序法。(取自百度百科)優化

咱們一樣以百度百科中的列子:假若有數字: 73, 22, 93, 43, 55, 14, 28, 65, 39, 81this

通過基數排序第一次掃描以後按照個位數的大小排序,數字被分配大以下的盒子中:

第0個盒子:
  第1個盒子:81
  第2個盒子:22
  第3個盒子:73, 93, 43
  第4個盒子:14
  第5個盒子:55, 65
  第6個盒子:
  第7個盒子:
  第8個盒子:28
  第9個盒子:39

根據盒子的順序,對數字經行第一次排序的結果以下:

81, 22, 73, 93, 43, 14, 55, 65, 28, 39

而後根據十位上的數值再將上次排序結果分配到不一樣的盒子裏

第0個盒子:
  第1個盒子:14 
  第2個盒子:22, 28
  第3個盒子:39
  第4個盒子:43
  第5個盒子:55
  第6個盒子:65
  第7個盒子:73
  第8個盒子:81
  第9個盒子:93

最後將盒子裏的數字取出,組成一個新的列表,該列表即爲排好順序的數字:
14, 22, 28, 39 ,43, 55, 65, 73, 81, 93

使用隊列表明盒子,能夠實現這個算法,咱們須要9個隊列,每一個對應一個數字。將全部隊列保存在一個數組中,使用取餘和出發操做決定各位和十位。算法的剩餘部分將數字加入對應的隊列,根據個位數值從新排序,而後再根據十位數值經行排序,結果即爲排好順序的數字。

function Queue(){
    var items = [];
    //入隊
    this.push = function(obj){
        items.push(obj);
    };

    //出隊
    this.pop = function(){
        return items.shift(); 
    };

    //獲取隊首
    this.getFirst = function(){
        return items[0];
    };

    //獲取隊尾
    this.getLast = function(){
        return items[items.length-1];
    };

    //清空本隊列
    this.clear = function(){
        items = [];
    }

    //獲取隊列指定位置
    this.get = function(k){
        return items[k];
    };

    //獲取隊列長度
    this.length = function(){
        return items.length;
    };

    //隊列是否爲空
    this.empty = function(){
        return items.length == 0;
    };
}

/********基數排序**********/

//初始化隊列
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);
}

console.log('初始化數組:', nums);

//按照個位數字入相應的隊列
for (var i=0; i<10; i++) {
    queues[nums[i]%10].push(nums[i]);
}

//收集隊列中的數字放在數組nums中
var j=0;
var nums2 = [];
for (var i=0; i<10; i++) {
    while (!queues[i].empty()){
        nums2[j++] = queues[i].pop();
    }
}

console.log('個位數字入隊排序後的數組:', nums2);

//因爲上面已經所有出隊了,因此可使用已經初始化的queue隊列數組

//按照十位數字入相應的隊列
for (var i = 0; i < 10; i++) {
    !isNaN(Math.floor(nums2[i] / 10)) && queues[Math.floor(nums2[i] / 10)].push(nums2[i]);
}

//收集隊列中的數字放在數組nums中
j=0;
var nums3 = []
for (var i=0; i<10; i++) {
    while (!queues[i].empty()){
        nums3[j++] = queues[i].pop();
    }
}

console.log('十位數字入隊排序後的數組:', nums3);

結果以下:

初始化數組: [15, 48, 46, 77, 23, 72, 93, 25, 0, 75]

個位數字入隊排序後的數組: [0, 72, 23, 93, 15, 25, 75, 46, 77, 48]

十位數字入隊排序後的數組: [0, 15, 23, 25, 46, 48, 72, 75, 77, 93]
相關文章
相關標籤/搜索