隊(duì)列(Queue)

隊(duì)列是一種先進(jìn)先出的線性數(shù)據(jù)結(jié)構(gòu)奶卓。

隊(duì)列的主要操作的是入隊(duì)和出隊(duì)晴音,需要從一端進(jìn)入肘交,從另外一端出去。

  • Queue接口定義

    public interface Queue<E> {
        int getSize();
        boolean isEmpty();
        void enqueue(E e);  //入隊(duì)
        E dequeue();        //出隊(duì)
        E getFront();       //獲取隊(duì)首元素
    }
    
  • 隊(duì)列可以使用數(shù)組實(shí)現(xiàn)唆缴,也可以使用鏈表實(shí)現(xiàn)

    //使用數(shù)組實(shí)現(xiàn)
    public ArrayQueue<E> implements Queue<E> {
        
        private Array<E> array;
        public ArrayQueue(int capacity) {
            array = new Array<>(capacity);
        }
        public ArrayQueue() {
            array = new Array<>();
        }
        
        public int getSize() {
            return array.getSize();
        }
        
        public boolean isEmpty() {
            return array.isEmpty();
        }
        
        public void enqueue(E e) {
            array.addLast(e);
        }
        
        public E dequeue() {
            return array.removeFirst();
        }
        
        public E getFront() {
            return array.getFirst();
        }
        
    }
    
    //使用鏈表實(shí)現(xiàn)
    public class LinkedListQueue<E> implements Queue<E> {
    
        //定義鏈表的節(jié)點(diǎn)
        private class Node {
            private E e;
            private Node next;
    
            public Node(E e, Node next) {
                this.e = e;
                this.next = next;
            }
            public Node(E e) {
                this(e, null);
            }
            @Override
            public String toString() {
                return e.toString();
            }
        }
    
        private Node head, tail;
        private int size = 0;
    
        public LinkedListQueue() {
            head = null;
            tail = null;
            size = 0;
        }
    
        @Override
        public int getSize() {
            return size;
        }
    
        @Override
        public boolean isEmpty() {
            return size == 0;
        }
    
        @Override
        public void enqueue(E e) {
            //由于沒有設(shè)置dummyHead,當(dāng)鏈表為空就需要單獨(dú)處理
            if(tail == null) {
                tail = new Node(e);
                head = tail;
            } else {
                tail.next = new Node(e);
                tail = tail.next;
            }
            size ++;
        }
    
        @Override
        public E dequeue() {
            if(isEmpty()){
                throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
            }
            Node retNode = head;
            //head指針后移
            head = head.next;
            retNode.next = null;
            if(head == null) {
                tail = null;
            }
            size --;
            return retNode.e;
        }
    
        @Override
        public E getFront() {
            if(isEmpty()){
                throw new IllegalArgumentException("Empty Queue.");
            }
            return head.e;
        }
    
        @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append("Queue: (front)");
    
        Node curr = head;
        while(curr != null) {
            if(curr.next != null) {
                res.append(curr + "->");
            }else{
                res.append(curr + "(tail) -> ");
            }
            curr = curr.next;
        }
        res.append("null");
        return res.toString();
    }
    }
    
  • 循環(huán)隊(duì)列

    正是因?yàn)檠h(huán)隊(duì)列在元素出隊(duì)操作的優(yōu)化(數(shù)組隊(duì)列的出隊(duì)操作鳍征,需要將剩余元素全部前移),才使得循環(huán)隊(duì)列的復(fù)雜度大大降低面徽。

    public class LoopQueue<E> implements Queue<E> {
    
        private E[] data;
        private int front, tail;
        private int size;
    
        public LoopQueue(int capacity) {
            //容量+1艳丛,是因?yàn)槲覀円室饫速M(fèi)一個(gè)空間
            data = (E[]) new Object[capacity + 1];
            front = 0;
            tail = 0;
            size = 0;
        }
    
        public LoopQueue() {
            this(10);
        }
    
        @Override
        public int getSize() {
            return size;
        }
    
        public int getCapacity() {
            return data.length-1;
        }
    
        @Override
        public boolean isEmpty() {
            return front == size;
        }
    
        @Override
        public void enqueue(E e) {
            //判斷是否堆滿
            if( (tail+1)%data.length == front) {
                resize(getCapacity() * 2);
            }
    
            //元素入隊(duì)
            data[tail] = e;
            //tail循環(huán)后移
            tail = (tail+1)%data.length;
            size ++;
        }
    
        private void resize(int newCapacity) {
            E[] newData = (E[]) new Object[newCapacity + 1];
            for (int i = 0; i < size; i++) {
                newData[i] = data[(i+front)%data.length];
            }
            data = newData;
            front = 0;
            tail = size;
        }
    
        @Override
        public E dequeue() {
            //隊(duì)列是否為空
            if(isEmpty()) {
                throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
            }
    
            E ret = data[front];
            data[front] = null;
            front = (front+1)%data.length;
            size --;
    
            //動(dòng)態(tài)縮容
            if(size == getCapacity() / 4 && getCapacity() /2 != 0) {
                resize(getCapacity() / 2);
            }
    
            return ret;
        }
    
        @Override
        public E getFront() {
            //隊(duì)列是否為空
            if(isEmpty()) {
                throw new IllegalArgumentException("Queue is empty.");
            }
            return data[front];
        }
    
        @Override
        public String toString() {
            StringBuilder res = new StringBuilder();
            res.append(String.format("LoopQueue:size = %d, capacity = %d\n", size, getCapacity()));
            res.append("front-> [");
            for (int i = front; i != tail ; i = (i+1)%data.length) {
                res.append(data[i]);
                if((i+1)%data.length != tail) {
                    res.append(", ");
                }
            }
            res.append("] <-tail\n");
            return res.toString();
        }
    }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市趟紊,隨后出現(xiàn)的幾起案子氮双,更是在濱河造成了極大的恐慌,老刑警劉巖霎匈,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件戴差,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡铛嘱,警方通過查閱死者的電腦和手機(jī)暖释,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墨吓,“玉大人球匕,你說我怎么就攤上這事√妫” “怎么了亮曹?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)秘症。 經(jīng)常有香客問我照卦,道長(zhǎng),這世上最難降的妖魔是什么历极? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任窄瘟,我火速辦了婚禮,結(jié)果婚禮上趟卸,老公的妹妹穿的比我還像新娘蹄葱。我一直安慰自己,他們只是感情好锄列,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布图云。 她就那樣靜靜地躺著,像睡著了一般邻邮。 火紅的嫁衣襯著肌膚如雪竣况。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天筒严,我揣著相機(jī)與錄音丹泉,去河邊找鬼情萤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛摹恨,可吹牛的內(nèi)容都是我干的筋岛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼晒哄,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼睁宰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寝凌,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤柒傻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后较木,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體红符,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年劫映,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了违孝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泳赋,死狀恐怖雌桑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祖今,我是刑警寧澤校坑,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站千诬,受9級(jí)特大地震影響耍目,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜徐绑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一邪驮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧傲茄,春花似錦毅访、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至草巡,卻和暖如春守呜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工查乒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弥喉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓侣颂,卻偏偏與公主長(zhǎng)得像档桃,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子憔晒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,694評(píng)論 0 3
  • 什么是數(shù)組? 數(shù)組簡(jiǎn)單來說就是將所有的數(shù)據(jù)排成一排存放在系統(tǒng)分配的一個(gè)內(nèi)存塊上蔑舞,通過使用特定元素的索引作為數(shù)組的下...
    啟明_b56f閱讀 892評(píng)論 0 0
  • 在Java多線程應(yīng)用中拒担,隊(duì)列的使用率很高,多數(shù)生產(chǎn)消費(fèi)模型的首選數(shù)據(jù)結(jié)構(gòu)就是隊(duì)列攻询。Java提供的線程安全的Queu...
    H_Man閱讀 473評(píng)論 0 4
  • queue是隊(duì)列(沒有迭代器从撼,就是說,不能用迭代器的iterator進(jìn)行遍歷) 首先加入: #include vo...
    貝克街的貓大哥呀閱讀 3,010評(píng)論 0 0
  • 說實(shí)話钧栖,寫這個(gè)不是游記的游記低零,更不算是詩的詩,心里很忐忑拯杠,我怕一個(gè)人看到掏婶,我同行的那個(gè)女伴(笑),她是個(gè)才女潭陪,我擔(dān)...
    大眼睛鼴鼠76閱讀 296評(píng)論 0 1