成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文詳解「隊列」,手擼隊列的3種方法!

存儲
前面我們介紹了棧(Stack),隊列和棧是比較像的一種數據結構。我們可以想象有很多輛汽車正在通過單行道的隧道,所有車輛不能插隊、不能掉頭,先進來的車也先出去,我們可以把這種特征的數據結構稱之為隊列。

 [[347452]]

本文已收錄至我的 Github《算法圖解》系列:https://github.com/vipstone/algorithm

前面我們介紹了棧(Stack),隊列和棧是比較像的一種數據結構。我們可以想象有很多輛汽車正在通過單行道的隧道,所有車輛不能插隊、不能掉頭,先進來的車也先出去,我們可以把這種特征的數據結構稱之為隊列。

 

 


隊列也屬于邏輯結構,所謂的物理結構是指可以將數據存儲在物理空間中,比如數組和鏈表都屬于物理數據結構;而邏輯結構則是用于描述數據間的邏輯關系的,它可以由多種不同的物理結構來實現,比如隊列和棧都屬于邏輯結構。

 

 

隊列特性

隊列中的元素必須是先進先出(First In First Out,FIFO)的,它有兩個重要的方法:入隊(enqueue)和出隊(dequeue)。隊列的入口端叫隊尾(rear),出口端叫隊頭(front),如下圖所示:

 

手擼隊列

學習了隊列的基本知識之后,接下來我們將使用代碼來實現一個隊列。

首先我們先使用數組來實現一個隊列,它的結構如下圖所示:

 

1.自定義隊列—數組

  1. public class MyQueue<E> { 
  2.  
  3.     private Object[] queue; // 存儲容器 
  4.     private int head; // 頭部指針 
  5.     private int tail; // 尾部指針 
  6.     private int size; // 隊列實際存儲長度 
  7.     private int maxSize; // 最大容量 
  8.  
  9.     public MyQueue() { 
  10.         // 無參構造函數,設置默認參數 
  11.         this.maxSize = 10; 
  12.         this.head = 0; 
  13.         this.tail = -1; 
  14.         this.size = 0; 
  15.         this.queue = new Object[this.maxSize]; 
  16.     } 
  17.  
  18.     public MyQueue(int initSize) { 
  19.         // 有參構造函數,設置參數 
  20.         this.maxSize = initSize; 
  21.         this.head = 0; 
  22.         this.tail = -1; 
  23.         this.size = 0; 
  24.         this.queue = new Object[this.maxSize]; 
  25.     } 
  26.  
  27.     /** 
  28.      * 查詢隊頭元素 
  29.      */ 
  30.     public E peek() throws Exception { 
  31.         if (size == 0) { 
  32.             throw new Exception("隊列中暫無數據"); 
  33.         } 
  34.         return (E) this.queue[this.head]; 
  35.     } 
  36.  
  37.     /** 
  38.      * 入列 
  39.      */ 
  40.     public boolean offer(E e) throws Exception { 
  41.         if (tail >= (maxSize - 1)) { 
  42.             throw new Exception("添加失敗,隊列已滿"); 
  43.         } 
  44.         this.queue[++tail] = e; 
  45.         size++; 
  46.         return true
  47.     } 
  48.  
  49.     /** 
  50.      * 出列 
  51.      */ 
  52.     public E poll() throws Exception { 
  53.         if (size == 0) { 
  54.             throw new Exception("刪除失敗,隊列為空"); 
  55.         } 
  56.         size--; 
  57.         return (E) this.queue[head++]; 
  58.     } 
  59.  
  60.     /** 
  61.      * 代碼測試 
  62.      */ 
  63.     public static void main(String[] args) throws Exception { 
  64.         MyQueue queue = new MyQueue(); 
  65.         queue.offer("Hello"); 
  66.         queue.offer("Java"); 
  67.         System.out.println(queue.peek()); 
  68.         queue.poll(); 
  69.         System.out.println(queue.poll()); 
  70.     } 

以上代碼的執行結果如下:

  • Hello
  • Java

2.自定義隊列—鏈表

用鏈表實現隊列的數據結構如下圖所示:

 

實現代碼如下:

  1. public class QueueByLinked { 
  2.  
  3.     /** 
  4.      * 聲明鏈表節點 
  5.      */ 
  6.     static class Node<E> { 
  7.         E item; // 當前的值 
  8.  
  9.         Node<E> next; // 下一個節點 
  10.  
  11.         Node(E e) { 
  12.             this.item = e; 
  13.         } 
  14.     } 
  15.  
  16.     private Node firstNode; // 隊頭元素 
  17.     private Node lastNode; // 隊尾元素 
  18.     private int size; // 隊列實際存儲數量 
  19.     private int maxSize; // 隊列最大容量 
  20.  
  21.     public QueueByLinked(int maxSize) { 
  22.         if (maxSize <= 0) throw new RuntimeException("隊列最大容量不能為空"); 
  23.         // 默認初始化函數 
  24.         firstNode = lastNode = new Node(null); 
  25.         this.size = 0; 
  26.         this.maxSize = maxSize; 
  27.     } 
  28.  
  29.     /** 
  30.      * 判斷隊列是否為空 
  31.      */ 
  32.     public boolean isEmpty() { 
  33.         return size == 0; 
  34.     } 
  35.  
  36.     /** 
  37.      * 入列 
  38.      */ 
  39.     public void offer(Object e) { 
  40.         // 最大值效驗 
  41.         if (maxSize <= size) throw new RuntimeException("隊列已滿"); 
  42.         Node node = new Node(e); 
  43.         lastNode = lastNode.next = node; // 設置最后一個節點和倒數第二個節點的 next 
  44.         size++; // 隊列數量 +1 
  45.     } 
  46.  
  47.     /** 
  48.      * 出列 
  49.      */ 
  50.     public Node poll() { 
  51.         if (isEmpty()) throw new RuntimeException("隊列為空"); 
  52.         size--; // 隊列數量 -1 
  53.         return firstNode = firstNode.next; // 設置并返回隊頭元素(第一個節點是 null,當前元素則為 Node.next) 
  54.     } 
  55.      
  56.     /** 
  57.      * 查詢隊頭元素 
  58.      */ 
  59.     public Node peek() { 
  60.         if (isEmpty()) throw new RuntimeException("隊列為空"); 
  61.         return firstNode.next;  // 返回隊頭元素(第一個節點是 null,當前元素則為 Node.next) 
  62.     } 
  63.  
  64.     /** 
  65.      * 代碼測試 
  66.      */ 
  67.     public static void main(String[] args) { 
  68.         QueueByLinked queue = new QueueByLinked(10); 
  69.         queue.offer("Hello"); 
  70.         queue.offer("JDK"); 
  71.         queue.offer("Java"); 
  72.         System.out.println(queue.poll().item); 
  73.         System.out.println(queue.poll().item); 
  74.         System.out.println(queue.poll().item); 
  75.     } 

以上代碼的執行結果如下:

  • Hello
  • JDK
  • Java

3.擴展:使用 List 實現自定義隊列

除了以上兩種方式之外,我們還可以使用 Java 自身的數據結構來實現隊列,比如 List,我們這里提供一個實現的思路(但并不建議在實際工作中使用),實現代碼如下:

  1. import java.util.ArrayList; 
  2. import java.util.List; 
  3.  
  4. /** 
  5.  * 自定義隊列(List方式) 
  6.  */ 
  7. public class QueueByList<E> { 
  8.  
  9.     private List value; // 隊列存儲容器 
  10.  
  11.     public QueueByList() { 
  12.         // 初始化 
  13.         value = new ArrayList(); 
  14.     } 
  15.  
  16.     /** 
  17.      * 判斷隊列是否為空 
  18.      */ 
  19.     public boolean isEmpty() { 
  20.         return value.size() == 0; 
  21.     } 
  22.  
  23.     /** 
  24.      * 入列 
  25.      */ 
  26.     public void offer(Object e) { 
  27.         value.add(e); 
  28.     } 
  29.  
  30.     /** 
  31.      * 出列 
  32.      */ 
  33.     public E poll() { 
  34.         if (isEmpty()) throw new RuntimeException("隊列為空"); 
  35.         E item = (E) value.get(0); 
  36.         value.remove(0); 
  37.         return item; 
  38.     } 
  39.  
  40.     /** 
  41.      * 查詢隊頭元素 
  42.      */ 
  43.     public E peek() { 
  44.         if (isEmpty()) throw new RuntimeException("隊列為空"); 
  45.         return (E) value.get(0); 
  46.     } 
  47.  
  48.     /** 
  49.      * 代碼測試 
  50.      */ 
  51.     public static void main(String[] args) { 
  52.         QueueByList queue = new QueueByList(); 
  53.         queue.offer("Hello"); 
  54.         queue.offer("JDK"); 
  55.         queue.offer("Java"); 
  56.         System.out.println(queue.poll()); 
  57.         System.out.println(queue.poll()); 
  58.         System.out.println(queue.poll()); 
  59.     } 

以上代碼的執行結果如下:

  • Hello
  • JDK
  • Java

隊列使用場景

隊列的常見使用場景有:

  • 存儲多線程中等待排隊執行的任務;
  • 存儲多線程公平鎖中等待執行任務的線程;
  • 常見消息中間件的任務隊列等。

總結

通過以上三種隊列的實現方式我們可以看出,任意容器都是可以用來實現隊列(Queue)的,只要保證隊列的元素先進先出(FIFO),并且在實現類中需要包含隊列的四個核心方法:入列、出列、查詢隊列是否為空、返回隊頭元素等,就可以稱為實現了一個自定義的隊列。

 

責任編輯:武曉燕 來源: Java中文社群
相關推薦

2019-08-23 12:12:49

MQ消息隊列

2023-12-15 09:45:21

阻塞接口

2024-10-08 08:52:59

2020-11-02 08:18:11

隊列數據

2021-10-20 07:18:51

Linux延時隊列

2024-04-28 08:14:29

C#隊列Queue

2024-05-30 08:05:17

2023-12-04 16:24:23

2023-11-01 11:06:18

2020-09-23 09:24:01

堆棧開發實現

2022-06-09 08:17:30

Python__new__

2025-04-08 08:01:31

2021-04-20 08:32:51

消息MQ隊列

2023-09-26 12:22:37

隊列Python

2022-06-26 00:18:05

企業產品化變量

2021-02-11 09:01:32

CSS開發 SDK

2020-12-01 09:30:34

區塊鏈

2022-03-01 20:41:00

機器學習特征人工智能

2022-08-18 15:52:13

開發者阿里云

2023-02-28 18:09:53

Javascript定時器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产伦精品一区二区 | www.中文字幕.com | 久草在线青青草 | 久久久免费观看视频 | 成人精品在线视频 | 99re6在线视频精品免费 | 中文字幕第九页 | 国产视频黄色 | 国产精品视频免费观看 | 免费一级片 | 免费在线色 | 国产玖玖 | 精品日韩欧美一区二区 | 99视频免费 | 亚洲国产精品一区二区三区 | 看片一区 | 日本久草 | 午夜天堂精品久久久久 | 99热视 | 欧美亚洲另类丝袜综合网动图 | 天天操伊人 | 亚洲国产精品人人爽夜夜爽 | 国产精品国产精品国产专区不卡 | 四虎影院新地址 | 国产传媒视频在线观看 | 午夜一区二区三区在线观看 | 激情五月综合 | 中文字幕在线一区二区三区 | 国产精品成人一区二区三区 | 久久er99热精品一区二区 | www.亚洲区 | 久久亚洲一区二区 | 一区二区三区四区在线视频 | 亚洲顶级毛片 | 久久国产精品视频免费看 | 欧美黄色一区 | 精品日韩一区二区 | 人人干人人干人人 | 日韩成人在线视频 | www操操 | 天堂一区 |