自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一文詳解「隊(duì)列」,手?jǐn)]隊(duì)列的3種方法!

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

 [[347452]]

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

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

 

 


隊(duì)列也屬于邏輯結(jié)構(gòu),所謂的物理結(jié)構(gòu)是指可以將數(shù)據(jù)存儲在物理空間中,比如數(shù)組和鏈表都屬于物理數(shù)據(jù)結(jié)構(gòu);而邏輯結(jié)構(gòu)則是用于描述數(shù)據(jù)間的邏輯關(guān)系的,它可以由多種不同的物理結(jié)構(gòu)來實(shí)現(xiàn),比如隊(duì)列和棧都屬于邏輯結(jié)構(gòu)。

 

 

隊(duì)列特性

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

 

手?jǐn)]隊(duì)列

學(xué)習(xí)了隊(duì)列的基本知識之后,接下來我們將使用代碼來實(shí)現(xiàn)一個隊(duì)列。

首先我們先使用數(shù)組來實(shí)現(xiàn)一個隊(duì)列,它的結(jié)構(gòu)如下圖所示:

 

1.自定義隊(duì)列—數(shù)組

  1. public class MyQueue<E> { 
  2.  
  3.     private Object[] queue; // 存儲容器 
  4.     private int head; // 頭部指針 
  5.     private int tail; // 尾部指針 
  6.     private int size; // 隊(duì)列實(shí)際存儲長度 
  7.     private int maxSize; // 最大容量 
  8.  
  9.     public MyQueue() { 
  10.         // 無參構(gòu)造函數(shù),設(shè)置默認(rèn)參數(shù) 
  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.         // 有參構(gòu)造函數(shù),設(shè)置參數(shù) 
  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.      * 查詢隊(duì)頭元素 
  29.      */ 
  30.     public E peek() throws Exception { 
  31.         if (size == 0) { 
  32.             throw new Exception("隊(duì)列中暫無數(shù)據(jù)"); 
  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("添加失敗,隊(duì)列已滿"); 
  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("刪除失敗,隊(duì)列為空"); 
  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.     } 

以上代碼的執(zhí)行結(jié)果如下:

  • Hello
  • Java

2.自定義隊(duì)列—鏈表

用鏈表實(shí)現(xiàn)隊(duì)列的數(shù)據(jù)結(jié)構(gòu)如下圖所示:

 

實(shí)現(xiàn)代碼如下:

  1. public class QueueByLinked { 
  2.  
  3.     /** 
  4.      * 聲明鏈表節(jié)點(diǎn) 
  5.      */ 
  6.     static class Node<E> { 
  7.         E item; // 當(dāng)前的值 
  8.  
  9.         Node<E> next; // 下一個節(jié)點(diǎn) 
  10.  
  11.         Node(E e) { 
  12.             this.item = e; 
  13.         } 
  14.     } 
  15.  
  16.     private Node firstNode; // 隊(duì)頭元素 
  17.     private Node lastNode; // 隊(duì)尾元素 
  18.     private int size; // 隊(duì)列實(shí)際存儲數(shù)量 
  19.     private int maxSize; // 隊(duì)列最大容量 
  20.  
  21.     public QueueByLinked(int maxSize) { 
  22.         if (maxSize <= 0) throw new RuntimeException("隊(duì)列最大容量不能為空"); 
  23.         // 默認(rèn)初始化函數(shù) 
  24.         firstNode = lastNode = new Node(null); 
  25.         this.size = 0; 
  26.         this.maxSize = maxSize; 
  27.     } 
  28.  
  29.     /** 
  30.      * 判斷隊(duì)列是否為空 
  31.      */ 
  32.     public boolean isEmpty() { 
  33.         return size == 0; 
  34.     } 
  35.  
  36.     /** 
  37.      * 入列 
  38.      */ 
  39.     public void offer(Object e) { 
  40.         // 最大值效驗(yàn) 
  41.         if (maxSize <= size) throw new RuntimeException("隊(duì)列已滿"); 
  42.         Node node = new Node(e); 
  43.         lastNode = lastNode.next = node; // 設(shè)置最后一個節(jié)點(diǎn)和倒數(shù)第二個節(jié)點(diǎn)的 next 
  44.         size++; // 隊(duì)列數(shù)量 +1 
  45.     } 
  46.  
  47.     /** 
  48.      * 出列 
  49.      */ 
  50.     public Node poll() { 
  51.         if (isEmpty()) throw new RuntimeException("隊(duì)列為空"); 
  52.         size--; // 隊(duì)列數(shù)量 -1 
  53.         return firstNode = firstNode.next; // 設(shè)置并返回隊(duì)頭元素(第一個節(jié)點(diǎn)是 null,當(dāng)前元素則為 Node.next) 
  54.     } 
  55.      
  56.     /** 
  57.      * 查詢隊(duì)頭元素 
  58.      */ 
  59.     public Node peek() { 
  60.         if (isEmpty()) throw new RuntimeException("隊(duì)列為空"); 
  61.         return firstNode.next;  // 返回隊(duì)頭元素(第一個節(jié)點(diǎn)是 null,當(dāng)前元素則為 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.     } 

以上代碼的執(zhí)行結(jié)果如下:

  • Hello
  • JDK
  • Java

3.擴(kuò)展:使用 List 實(shí)現(xiàn)自定義隊(duì)列

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

  1. import java.util.ArrayList; 
  2. import java.util.List; 
  3.  
  4. /** 
  5.  * 自定義隊(duì)列(List方式) 
  6.  */ 
  7. public class QueueByList<E> { 
  8.  
  9.     private List value; // 隊(duì)列存儲容器 
  10.  
  11.     public QueueByList() { 
  12.         // 初始化 
  13.         value = new ArrayList(); 
  14.     } 
  15.  
  16.     /** 
  17.      * 判斷隊(duì)列是否為空 
  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("隊(duì)列為空"); 
  35.         E item = (E) value.get(0); 
  36.         value.remove(0); 
  37.         return item; 
  38.     } 
  39.  
  40.     /** 
  41.      * 查詢隊(duì)頭元素 
  42.      */ 
  43.     public E peek() { 
  44.         if (isEmpty()) throw new RuntimeException("隊(duì)列為空"); 
  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.     } 

以上代碼的執(zhí)行結(jié)果如下:

  • Hello
  • JDK
  • Java

隊(duì)列使用場景

隊(duì)列的常見使用場景有:

  • 存儲多線程中等待排隊(duì)執(zhí)行的任務(wù);
  • 存儲多線程公平鎖中等待執(zhí)行任務(wù)的線程;
  • 常見消息中間件的任務(wù)隊(duì)列等。

總結(jié)

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

 

責(zé)任編輯:武曉燕 來源: Java中文社群
相關(guān)推薦

2019-08-23 12:12:49

MQ消息隊(duì)列

2023-12-15 09:45:21

阻塞接口

2024-10-08 08:52:59

2020-11-02 08:18:11

隊(duì)列數(shù)據(jù)

2021-10-20 07:18:51

Linux延時隊(duì)列

2024-04-28 08:14:29

C#隊(duì)列Queue

2024-05-30 08:05:17

2023-11-01 11:06:18

2023-12-04 16:24:23

2020-09-23 09:24:01

堆棧開發(fā)實(shí)現(xiàn)

2022-06-09 08:17:30

Python__new__

2025-04-08 08:01:31

2021-04-20 08:32:51

消息MQ隊(duì)列

2023-09-26 12:22:37

隊(duì)列Python

2022-06-26 00:18:05

企業(yè)產(chǎn)品化變量

2021-02-11 09:01:32

CSS開發(fā) SDK

2020-12-01 09:30:34

區(qū)塊鏈

2022-03-01 20:41:00

機(jī)器學(xué)習(xí)特征人工智能

2009-07-23 15:17:54

JDBC連接Acces

2009-03-31 13:12:30

解析XMLJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號