數(shù)據(jù)結(jié)構(gòu)與算法(2) - 隊列

哈嘍各位小伙伴杠纵,接著上一篇介紹了棧這個數(shù)據(jù)結(jié)構(gòu)比藻,這一篇我們來說一下隊列倘屹,上一篇沒看的同學(xué)可以先去看一下 數(shù)據(jù)結(jié)構(gòu)與算法(1) - 棧

隊列的定義

隊列是一種特殊的線性表纽匙,其特殊之處在于烛缔,它只允許你在隊列的頭部刪除元素,在隊列的末尾添加新的元素烟央。
下面這張圖展示了隊列如何添加新的元素


隊列1.png

左側(cè)是隊列的頭部,右側(cè)是隊列的尾部,新的元素如果想進(jìn)入隊列梯影,只能從尾部進(jìn)入,如果想要出隊列甲棍,只能從隊列的頭部出去,下面的圖展示了元素如何出隊列


隊列2.png

日常生活中感猛,排隊就是典型的隊列結(jié)構(gòu)陪白,下面這幅圖里膳灶,大家在排隊辦理登機(jī)手續(xù)。
隊列3.jpeg

1. 隊列的實現(xiàn)

有了棧這個數(shù)據(jù)結(jié)構(gòu)做鋪墊序厉,隊列就很容易學(xué)了

數(shù)據(jù)存儲

同棧一樣弛房,本課程里隊列的實現(xiàn)也使用數(shù)組來存儲數(shù)據(jù)霉晕,定義一個簡單的Queue類

function Queue(){
    var items = [];   // 存儲數(shù)據(jù)
};

2. 隊列的方法

隊列的方法如下:

  • enqueue 從隊列尾部添加一個元素(新來一個排隊的人拄轻,文明禮貌伟葫,站在了隊伍末尾)
  • dequeue 從隊列頭部刪除一個元素(排隊伍最前面的人剛辦理完登機(jī)手續(xù),離開了隊伍)
  • head 返回頭部的元素常拓,注意弄抬,不是刪除(只是看一下掂恕,誰排在最前面)
  • size 返回隊列大邪猛觥(數(shù)一數(shù)有多少人在排隊)
  • clear 清空隊列(航班取消乎串,大家都散了吧)
  • isEmpty 判斷隊列是否為空 (看看是不是有人在排隊)
  • tail 返回隊列尾節(jié)點
2.1 enqueue方法
// 向隊列尾部添加一個元素
    this.enqueue = function(item){
        items.push(item);
    };
2.2 dequeue方法
// 移除隊列頭部的元素
    this.dequeue = function(){
        return items.shift();
    };
2.3 head方法
// 返回隊列頭部的元素
    this.head = function(){
        return items[0];
    }
2.4 size方法
// 返回隊列大小
    this.size = function(){
        return items.length;
    }

2.5 clear方法

// clear
    this.clear = function(){
        items = [];
    }
2.6 isEmpty方法
// isEmpty 判斷是否為空隊列
    this.isEmpty = function(){
        return items.length == 0;
    }
2.7 tail方法
// 返回隊列尾部的元素
    this.tail = function(){
        return items[items.length-1];
    };

完整代碼如下


function Queue(){
    var items = [];   // 存儲數(shù)據(jù)

    // 向隊列尾部添加一個元素
    this.enqueue = function(item){
        items.push(item);
    };

    // 移除隊列頭部的元素
    this.dequeue = function(){
        return items.shift();
    };

    // 返回隊列頭部的元素
    this.head = function(){
        return items[0];
    }

    // 返回隊列大小
    this.size = function(){
        return items.length;
    }

    // clear
    this.clear = function(){
        items = [];
    }

    // isEmpty 判斷是否為空隊列
    this.isEmpty = function(){
        return items.length == 0;
    }
};

3.隊列的應(yīng)用

3.1 約瑟夫環(huán)
3.1.1 題目要求

有一個數(shù)組a[100]存放0--99;要求每隔兩個數(shù)刪掉一個數(shù)店枣,到末尾時循環(huán)至開頭繼續(xù)進(jìn)行,求最后一個被刪掉的數(shù)叹誉。

3.1.2 思路分析

前10個數(shù)是 0 1 2 3 4 5 6 7 8 9 10鸯两,所謂每隔兩個數(shù)刪掉一個數(shù),其實就是把 2 5 8 刪除掉桂对,如果只是從0 到 99 每個兩個數(shù)刪掉一個數(shù)甩卓,其實挺簡單的鸠匀,可是題目要求到末尾時還有循環(huán)至開頭繼續(xù)進(jìn)行蕉斜。

如果是用數(shù)組,問題就又顯得麻煩了缀棍,關(guān)鍵是到了末尾如何回到開頭重新來一遍宅此,還得考慮把刪除掉的元素從數(shù)組中刪除父腕。

如果用隊列就簡單了,先將這100個數(shù)放入隊列,使用while循環(huán),while循環(huán)終止的條件是隊列里只有一個元素竞阐。使用index變量從0開始計數(shù),算法步驟如下:

1. 從隊列頭部刪除一個元素峭火,index+1
2. 如果index%3 == 0,就說明這個元素是需要刪除的元素稍浆,如果不等于0,就不是需要被刪除的元素,則把它添加到隊列的尾部

不停的有元素被刪除益楼,最終隊列里只有一個元素粒督,此時while循環(huán)終止,隊列的所剩的元素就是最后一個被刪除的元素。

3.1.3 示例代碼
function del_ring(arr_list){
    // 把數(shù)組里的元素都放入到隊列中
    var queue = new Queue();
    for(var i=0;i< arr_list.length;i++){
        queue.enqueue(arr_list[i]);
    }

    var index = 0;
    while(queue.size() != 1){
        // 彈出一個元素,判斷是否需要刪除
        var item = queue.dequeue();
        index += 1;
        // 每隔兩個就要刪除掉一個,那么不是被刪除的元素就放回到隊列尾部
        if(index %3 != 0){
            queue.enqueue(item);
        }
    }

    return queue.head();
};

// 準(zhǔn)備好數(shù)據(jù)
var arr_list = [];
for(var i=0;i< 100;i++){
    arr_list.push(i);
}


console.log(del_ring(arr_list));
3.2 斐波那契數(shù)列

斐波那契數(shù)列是一個非常經(jīng)典的問題,有著各種各樣的解法劳翰,比較常見的是遞歸算法颖变,其實也可以使用隊列來實現(xiàn)

3.2.1 題目要求

計算斐波那契數(shù)列的第n項

3.2.2 思路分析

斐波那契數(shù)列的前兩項是 1 1 马胧,此后的每一項都是該項前面兩項之和垫卤,即f(n) = f(n-1) + f(n-2)。

如果使用數(shù)組來實現(xiàn),究竟有多麻煩了我就不贅述了,直接考慮使用隊列來實現(xiàn)。

先將兩個1 添加到隊列中,之后使用while循環(huán)厌均,用index計數(shù)擒悬,循環(huán)終止的條件是index < n -2

  • 使用dequeue方法從隊列頭部刪除一個元素僧凤,該元素為del_item
  • 使用head方法獲得隊列頭部的元素澎语,該元素為 head_item
  • del_item + head_item = next_item,將next_item放入隊列盯孙,注意骑晶,只能從尾部添加元素
  • index+1
    當(dāng)循環(huán)結(jié)束時漫谷,隊列里面有兩個元素惕稻,先用dequeue 刪除頭部元素俺祠,剩下的那個元素就是我們想要的答案
3.2.3 示例代碼
function fibonacci(n){
    queue = new Queue();
    var index = 0;
    // 先放入斐波那契序列的前兩個數(shù)值
    queue.enqueue(1);
    queue.enqueue(1);
    while(index < n-2){
        // 出隊列一個元素
        var del_item = queue.dequeue();
        // 取隊列頭部元素
        var head_item = queue.head();
        var next_item = del_item + head_item;
        // 將計算結(jié)果放入隊列
        queue.enqueue(next_item);
        index += 1;
    }

    queue.dequeue();
    return queue.head();
};


console.log(fibonacci(8));

小結(jié)

數(shù)據(jù)結(jié)構(gòu)在系統(tǒng)設(shè)計中的應(yīng)用非常廣泛,只是我們水平達(dá)不到那個級別淌铐,知道的太少,但如果能理解并掌握這些數(shù)據(jù)結(jié)構(gòu),那么就有機(jī)會在工作中使用它們并解決一些具體的問題释涛,當(dāng)我們手里除了錘子還有電鋸時唇撬,那么我們的眼里就不只是釘子烧给,解決問題的思路也會更加開闊酝惧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市艰山,隨后出現(xiàn)的幾起案子咏闪,更是在濱河造成了極大的恐慌曙搬,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸽嫂,死亡現(xiàn)場離奇詭異纵装,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)据某,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門橡娄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人癣籽,你說我怎么就攤上這事挽唉。” “怎么了筷狼?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵瓶籽,是天一觀的道長。 經(jīng)常有香客問我埂材,道長塑顺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任楞遏,我火速辦了婚禮茬暇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寡喝。我一直安慰自己糙俗,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布预鬓。 她就那樣靜靜地躺著巧骚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪格二。 梳的紋絲不亂的頭發(fā)上劈彪,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機(jī)與錄音顶猜,去河邊找鬼沧奴。 笑死,一個胖子當(dāng)著我的面吹牛长窄,可吹牛的內(nèi)容都是我干的滔吠。 我是一名探鬼主播纲菌,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疮绷!你這毒婦竟也來了翰舌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤冬骚,失蹤者是張志新(化名)和其女友劉穎椅贱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體只冻,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡庇麦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了属愤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片女器。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖住诸,靈堂內(nèi)的尸體忽然破棺而出驾胆,到底是詐尸還是另有隱情,我是刑警寧澤贱呐,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布丧诺,位于F島的核電站,受9級特大地震影響奄薇,放射性物質(zhì)發(fā)生泄漏驳阎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一馁蒂、第九天 我趴在偏房一處隱蔽的房頂上張望呵晚。 院中可真熱鬧,春花似錦沫屡、人聲如沸饵隙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽金矛。三九已至,卻和暖如春勺届,著一層夾襖步出監(jiān)牢的瞬間驶俊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工免姿, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留饼酿,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓胚膊,卻偏偏與公主長得像嗜湃,于是被迫代替她去往敵國和親奈应。 傳聞我的和親對象是個殘疾皇子澜掩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容