數據結構與算法—隊列圖文詳解

前言

  • 棧和隊列是一對好兄弟,前面咱們介紹過數據結構與算法—棧詳解,那麼棧的機制相對簡單,後入先出,就像進入一個狹小的山洞,山洞只有一個出口,只能後進先出(在外面的先出去)。而隊列就比如是一個隧道,後面的人跟着前面走,前面人先出去(先入先出)。平常的排隊就是隊列運轉形式的一個描述!
  • 因此隊列的核心理念就是:先進先出
  • 隊列的概念:隊列是一種特殊的線性表,特殊之處在於它只容許在表的前端(front)進行刪除操做,而在表的後端(rear)進行插入操做,和棧同樣,隊列是一種操做受限制的線性表。進行插入操做的端稱爲隊尾,進行刪除操做的端稱爲隊頭
  • 同時,閱讀本偏文章最好先弄懂順序表的基本操做和棧的數據結構!學習效果更佳!
    在這裏插入圖片描述

隊列介紹

基本屬性

隊頭front:前端

  • 刪除數據的一端。對於數組,從後面插入更容易,前面插入較困難,因此通常用數組實現的隊列隊頭在前面。(刪除直接index遊標前進,不超過隊尾便可)。而對於鏈表。插入刪除在兩頭分別進行那麼頭部(前面)刪除尾部插入是最方便的選擇。

隊尾rear:java

  • 插入數據的一端,同上,在數組和鏈表中一般均在尾部位置。固然,其實數組和鏈表的front和rear還有點小區別,後面會具體介紹。

enQueue(入隊):node

  • 隊尾rear插入元素

deQueue(出隊):算法

  • 對頭front刪除元素

普通隊列

按照上述的介紹,咱們很容易知道數組實現的方式。用數組模擬表示隊列。要考慮初始化,插入,問題。
在這裏插入圖片描述後端

  • 初始化:數組的front和rear都指向0.
  • 入隊:隊不滿數組不越界,先隊尾位置傳值,再隊尾下標+1
  • 出隊:隊不空,先取隊頭位置元素,在隊頭+1,

可是很容易發現問題,每一個空間域只能利用一次。形成空間極度浪費。而且很是容易越界
在這裏插入圖片描述數組

循環隊列

針對上述的問題。有個較好的解決方法!就是對已經申請的(數組)內存重複利用。這就是咱們所說的循環隊列。數據結構

而數組實現的循環隊列就是在邏輯上稍做修改。咱們假設(約定)數組的最後一位的下一個index是首位。由於咱們隊列中只須要front和tail兩個指標。不須要數組的實際地址位置相關數據。和它無關。因此咱們就只須要考慮尾部的特殊操做便可。數據結構和算法

  • 初始化:數組的front和rear都指向0.
  • 入隊:不滿,先隊尾位置傳值,再rear=(rear + 1) % maxsize;
  • 出隊:隊不空,先取隊頭位置元素,front=(front + 1)%maxsize;
  • 是否爲空:return rear == front;
  • 大小:return (rear+maxsize-front)%maxsize;

這裏面有幾個你們須要注意的,就是指標相加若是遇到最後須要轉到頭的話。能夠判斷是否到數組末尾位置。也能夠直接+1求餘。其中maxsize是數組實際大小。
在這裏插入圖片描述學習

鏈式實現

對於鏈表實現的隊列,要根據先進先出的規則考慮頭和尾的位置this

咱們知道隊列是先進先出的,對於鏈表,咱們能採用單鏈表儘可能採用單鏈表,能方便儘可能方便,同時還要兼顧效率

  • 方案一 若是隊頭設在鏈表尾,隊尾設在鏈表頭。那麼隊尾進隊插入在鏈表頭部插入沒問題。容易實現,可是若是隊頭刪除在尾部進行,若是不設置尾指針要遍歷到隊尾,可是設置尾指針刪除須要將它指向前驅節點那麼就須要雙向鏈表。都挺麻煩的。

  • 方案二可是若是隊頭設在鏈表頭,隊尾設在鏈表尾部,那麼隊尾進隊插入在鏈表尾部插入沒問題(用尾指針能夠直接指向next)。容易實現,若是隊頭刪除在頭部進行也很容易,就是咱們前面常說的頭節點刪除節點。

  • 因此咱們最終採起的是方案2的帶頭節點,帶尾指針的單鏈表!

主要操做爲:

  • 初始化:
public class listQueue<T> { static class node<T> { T data;// 節點的結果 node next;// 下一個鏈接的節點 public node() {} public node(T data) { this.data = data; } } node front;//至關於head 帶頭節點的 node rear;//至關於tail/end public listQueue() { front=new node<T>(); rear=front; } 
  • 入隊:rear.next=va;rear=va;(va爲被插入節點)
    在這裏插入圖片描述
  • 出隊:隊不空,front.next=front.next.next;經典帶頭節點刪除
    在這裏插入圖片描述
  • 是否爲空:return rear == front;
  • 大小:節點front遍歷到rear的個數。

具體實現

數組實現

package 隊棧; public class seqQueue<T> { private T data[];// 數組容器 private int front;// 頭 private int rear;// 尾 private int maxsize;// 最大長度 public seqQueue(int i)// 設置長爲i的int 型隊列 { data = (T[]) new Object[i+1]; front = 0; rear = 0; maxsize = i+1; } public int lenth() { return (rear+maxsize-front)%maxsize; } public boolean isempty() { return rear == front; } public boolean isfull() { return (rear + 1) % maxsize == front; } public void enQueue(T i) throws Exception// 入隊 { if (isfull()) throw new Exception("已滿"); else { data[rear] = i; rear=(rear + 1) % maxsize; } } public T deQueue() throws Exception// 出隊 { if (isempty()) throw new Exception("已空"); else { T va=data[front]; front=(front+1)%maxsize; return va; } } public String toString()// 輸出隊 { String va="隊頭: "; int lenth=lenth(); for(int i=0;i<lenth;i++) { va+=data[(front+i)%maxsize]+" "; } return va; } } 

鏈式實現

package 隊棧; public class listQueue<T> { static class node<T> { T data;// 節點的結果 node next;// 下一個鏈接的節點 public node() {} public node(T data) { this.data = data; } } node front;//至關於head 帶頭節點的 node rear;//至關於tail/end public listQueue() { front=new node<T>(); rear=front; } public int lenth() { int len=0; node team=front; while(team!=rear) { len++;team=team.next; } return len; } public boolean isempty() { return rear == front; } public void enQueue(T value) // 入隊.尾部插入 { node va=new node<T>(value); rear.next=va; rear=va; } public T deQueue() throws Exception// 出隊 { if (isempty()) throw new Exception("已空"); else { T va=(T) front.next.data; front.next=front.next.next; return va; } } public String toString() { node team=front.next; String va="隊頭: "; while(team!=null) { va+=team.data+" "; team=team.next; } return va; } } 

測試

在這裏插入圖片描述

總結

  • 對於隊列來講數據結構相比棧複雜一些,可是也不是很難,搞懂先進先出而後就用數組或者鏈表實現便可。
  • 對於數組,隊尾tail指向的位置是空的,而鏈表的front(head同樣)爲頭指針爲空的,因此在不一樣結構實現相同效果的方法須要注意一下。
  • 對於雙向隊列,你們能夠自行了解,雙向隊列兩邊都可插入刪除,可以實現堆棧公用等更加靈活調用的結果。(參考java的ArrayDeque).而且如今的消息隊列等不少中間件都是基於隊列模型延申。因此學會隊列很重要!
  • 最後,筆者水平有限,若是有紕漏和不足之處還請指出。另外,若是感受不錯能夠點個贊,關注我的公衆號:bigsai 更多常常與你分享,關注回覆數據結構獲取精心準備的數據結構和算法資料多份
    在這裏插入圖片描述
相關文章
相關標籤/搜索