數(shù)據(jù)結(jié)構(gòu) - 隊(duì)列

數(shù)據(jù)結(jié)構(gòu)和算法動(dòng)態(tài)可視化網(wǎng)站

一玛瘸、隊(duì)列 Queue

隊(duì)列是一種特殊的線性表,只能在頭尾兩端進(jìn)行操作砰琢;

隊(duì)尾(rear):只能從隊(duì)尾添加元素魁索,一般叫做 enQueue,入隊(duì)
隊(duì)頭(front):只能從隊(duì)頭移除元素炬灭,一般叫做 deQueue,出隊(duì)
先進(jìn)先出的原則靡菇,First In First Out重归,F(xiàn)IFO

image.png

隊(duì)列的內(nèi)部實(shí)現(xiàn)可以使用動(dòng)態(tài)數(shù)組雙向鏈表實(shí)現(xiàn),優(yōu)先使用雙向鏈表厦凤,因?yàn)殛?duì)列主要是往頭尾操作元素鼻吮。

二、隊(duì)列的接口設(shè)計(jì)

public class Queue<E> {
    // 使用雙向鏈表實(shí)現(xiàn)隊(duì)列
    private List<E> list = new LinkedList<>();
    // 元素的數(shù)量
    public int size();
    // 是否為空
    public boolean isEmpty();
    // 入隊(duì)
    public void enQueue(E element);
    // 出隊(duì)
    public E deQueue();
    // 獲取隊(duì)列的頭元素
    public E front();
}

三较鼓、隊(duì)列的實(shí)現(xiàn)

public class Queue <E>{
    private List<E> list = new LinkedList<>();
    public void enQueue(E element){
        list.add(element);
    }
    public E deQueue(){
        return list.remove(0);
    }
    public int size(){
        return list.size();
    }
    public void clear(){
        list.clear();
    }
    public E top(){
        return list.get(0);
    }
    public boolean isEmpty(){
        return list.isEmpty();
    }
}

四椎木、雙端隊(duì)列 (Deque)

雙端隊(duì)列是能在頭尾兩端添加、刪除的隊(duì)列博烂;
英文 dequedouble ended queue 的簡(jiǎn)稱

雙端隊(duì)列接口設(shè)計(jì)

int size(); // 元素的數(shù)量
boolean isEmpty(); // 是否為空
void clear(); // 清空
void enQueueRear(E element); // 從隊(duì)尾入隊(duì)
E deQueueFront(); // 從隊(duì)頭出隊(duì)
void enQueueFront(E element); // 從隊(duì)頭入隊(duì)
E deQueueRear(); // 從隊(duì)尾出隊(duì)
E front(); // 獲取隊(duì)列的頭元素
E rear(); // 獲取隊(duì)列的尾元素

雙端隊(duì)列實(shí)現(xiàn)

public class Deque<E> {
    private List<E> list = new LinkedList<>();
    
    // 元素的數(shù)量
    public int size() {
        return list.size();
    }
    // 是否為空
    public boolean isEmpty() {
        return list.isEmpty();
    }
    // 從隊(duì)頭出隊(duì)
    public E deQueueFront() {
        return list.remove(0);
    }
    // 從隊(duì)頭入隊(duì)
    public void enQueueFront(E element) {
        list.add(0, element);
    }
    // 從隊(duì)尾入隊(duì)
    public void enQueueRear(E element) {
        list.add(element);
    }
    // 從隊(duì)尾出隊(duì)
    public E deQueueRear() {
        return list.remove(list.size() - 1);
    }
    // 獲取隊(duì)列的頭元素
    public E front() {
        return list.get(0);
    }
    // 獲取隊(duì)列的尾元素
    public E rear() {
        return list.get(list.size() - 1);
    }
}

五香椎、循環(huán)隊(duì)列

隊(duì)列內(nèi)部實(shí)現(xiàn)也可以用動(dòng)態(tài)數(shù)組實(shí)現(xiàn),并且將各項(xiàng)接口優(yōu)化到O(1)的時(shí)間復(fù)雜度禽篱, 這個(gè)用數(shù)組實(shí)現(xiàn)并優(yōu)化之后的隊(duì)列就叫做: 循環(huán)隊(duì)列畜伐。

image.png
  • 使用一個(gè)索引變量front控制第0個(gè)元素所在位置。
  • 每一次出棧躺率,就將front位置的元素取出并刪除玛界,然后front向后+1万矾。
  • 每一次入棧,都根據(jù)front和當(dāng)前元素?cái)?shù)量計(jì)算出入棧元素應(yīng)該存入的索引慎框,然后將元素存入到數(shù)組對(duì)應(yīng)索引的位置上勤众。

循環(huán)隊(duì)列的接口設(shè)計(jì)

public class CircleQueue<E> {
    // 記錄第0個(gè)元素的索引
    private int front;
    // 當(dāng)前隊(duì)列存儲(chǔ)的元素個(gè)數(shù)
    private int size;
    // 用來(lái)存儲(chǔ)元素的數(shù)組
    private E[] elements;
    // 當(dāng)前隊(duì)列存儲(chǔ)的元素?cái)?shù)量
    public int size();
    // 當(dāng)前隊(duì)列是否為空
    public boolean isEmpty();
    // 入隊(duì)
    public void enQueue(E element);
    // 出隊(duì)
    public E deQueue();
    // 查看索引為0的元素
    public E front();
}

循環(huán)隊(duì)列的實(shí)現(xiàn)

1、構(gòu)造方法

public class ArrayList<E> {
    private E[] elements;
    // 設(shè)置elements數(shù)組默認(rèn)的初始化空間
    private static final int DEFAULT_CAPACITY = 10;
    
    public CircleQueue() {
        elements = (E[]) new Object[DEFAULT_CAPACITY];
    }
}

2鲤脏、入隊(duì)

  • 入隊(duì)前需要考慮兩個(gè)問(wèn)題:隊(duì)列是否需要擴(kuò)容計(jì)算入隊(duì)實(shí)際索引们颜。

擴(kuò)容相關(guān)內(nèi)容請(qǐng)閱讀《動(dòng)態(tài)數(shù)組》一章

  • 擴(kuò)容后front 需要重置為0
image.png
private void ensureCapacity(int capacity) {
    int oldCapacity = elements.length;
    if (oldCapacity >= capacity) return;
        
    // 新容量為舊容量的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1); //位運(yùn)算
    E[] newElements = (E[]) new Object[newCapacity];
    for (int i = 0; i < size; i++) {
        newElements[i] = elements[index(i)];
    }
    elements = newElements;
        
    // 重置front
    front = 0;
}

3、索引計(jì)算

  • 預(yù)期入隊(duì)索引 = 第0個(gè)元素索引 + 當(dāng)前隊(duì)列元素個(gè)數(shù)猎醇。
  • 如果預(yù)期入隊(duì)索引大于等于數(shù)組長(zhǎng)度窥突,實(shí)際入隊(duì)索引 = 預(yù)期入隊(duì)索引 - 數(shù)組長(zhǎng)度。
  • 如果預(yù)期入隊(duì)索引小于數(shù)組長(zhǎng)度硫嘶,實(shí)際入隊(duì)索引 = 預(yù)期入隊(duì)索引阻问。
// 索引計(jì)算
private int index(int index) {
    index += front;
    return index - (index >= elements.length ? elements.length : 0);
}

// 入隊(duì)的代碼
public void enQueue(E element) {
    // 數(shù)組擴(kuò)容判斷
    ensureCapacity(size + 1);
    // 索引計(jì)算,并賦值
    elements[index(size)] = element;
    // size加一
    size++;
}

4沦疾、出隊(duì)

出隊(duì)后需要更新front

public E deQueue() {
    // 獲取出隊(duì)元素
    E frontElement = elements[front];
    // 將索引位置致空
    elements[front] = null;
    // 更新font
    front = index(1);
    // size減一
    size--;
    // 返回出隊(duì)元素
    return frontElement;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末称近,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哮塞,更是在濱河造成了極大的恐慌刨秆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忆畅,死亡現(xiàn)場(chǎng)離奇詭異衡未,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)家凯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門缓醋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人绊诲,你說(shuō)我怎么就攤上這事送粱。” “怎么了掂之?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵抗俄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我板惑,道長(zhǎng)橄镜,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任冯乘,我火速辦了婚禮,結(jié)果婚禮上晒夹,老公的妹妹穿的比我還像新娘裆馒。我一直安慰自己姊氓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布喷好。 她就那樣靜靜地躺著翔横,像睡著了一般。 火紅的嫁衣襯著肌膚如雪梗搅。 梳的紋絲不亂的頭發(fā)上禾唁,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音无切,去河邊找鬼荡短。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哆键,可吹牛的內(nèi)容都是我干的掘托。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼籍嘹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闪盔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起辱士,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤泪掀,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后颂碘,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體族淮,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年凭涂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祝辣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡切油,死狀恐怖蝙斜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情澎胡,我是刑警寧澤孕荠,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站攻谁,受9級(jí)特大地震影響稚伍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜戚宦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一个曙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧受楼,春花似錦垦搬、人聲如沸呼寸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)对雪。三九已至,卻和暖如春米绕,著一層夾襖步出監(jiān)牢的瞬間瑟捣,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工栅干, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迈套,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓非驮,卻偏偏與公主長(zhǎng)得像交汤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子劫笙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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