From e20bc251f58f26e95dc366b9dde98081639642d6 Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Fri, 2 Dec 2022 00:09:34 +0800 Subject: [PATCH] Add python code of chapter queue to docs. --- .../chapter_array_and_linkedlist/my_list.cpp | 5 +- .../chapter_stack_and_queue/array_queue.cpp | 7 +- .../go/chapter_stack_and_queue/array_queue.go | 2 +- .../chapter_array_and_linkedlist/my_list.java | 13 +- .../chapter_stack_and_queue/array_queue.java | 7 +- .../javascript/chapter_sorting/bubble_sort.js | 2 +- .../chapter_sorting/insertion_sort.js | 2 +- .../javascript/chapter_sorting/merge_sort.js | 2 +- .../chapter_array_and_linkedlist/my_list.py | 3 +- .../chapter_stack_and_queue/array_queue.py | 48 +++--- codes/python/chapter_stack_and_queue/deque.py | 30 ++-- .../linkedlist_queue.py | 33 ++-- codes/python/chapter_stack_and_queue/queue.py | 40 ++--- codes/python/include/__init__.py | 1 + codes/python/include/print_util.py | 3 +- docs/chapter_array_and_linkedlist/list.md | 29 ++-- docs/chapter_stack_and_queue/deque.md | 24 ++- docs/chapter_stack_and_queue/queue.md | 159 +++++++++++++++--- 18 files changed, 276 insertions(+), 134 deletions(-) diff --git a/codes/cpp/chapter_array_and_linkedlist/my_list.cpp b/codes/cpp/chapter_array_and_linkedlist/my_list.cpp index 48d0cdb..f64bd27 100644 --- a/codes/cpp/chapter_array_and_linkedlist/my_list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/my_list.cpp @@ -72,15 +72,18 @@ public: } /* 删除元素 */ - void remove(int index) { + int remove(int index) { if (index >= size()) throw out_of_range("索引越界"); + int num = nums[index]; // 索引 i 之后的元素都向前移动一位 for (int j = index; j < size() - 1; j++) { nums[j] = nums[j + 1]; } // 更新元素数量 numsSize--; + // 返回被删除元素 + return num; } /* 列表扩容 */ diff --git a/codes/cpp/chapter_stack_and_queue/array_queue.cpp b/codes/cpp/chapter_stack_and_queue/array_queue.cpp index e98caa2..8bc6a93 100644 --- a/codes/cpp/chapter_stack_and_queue/array_queue.cpp +++ b/codes/cpp/chapter_stack_and_queue/array_queue.cpp @@ -51,11 +51,8 @@ public: /* 出队 */ int poll() { - // 删除头结点 - if (empty()) - throw out_of_range("队列为空"); - int num = nums[front]; - // 队头指针向后移动,越过尾部后返回到数组头部 + int num = peek(); + // 队头指针向后移动一位,若越过尾部则返回到数组头部 front = (front + 1) % capacity(); return num; } diff --git a/codes/go/chapter_stack_and_queue/array_queue.go b/codes/go/chapter_stack_and_queue/array_queue.go index f771ea2..fd41f8b 100644 --- a/codes/go/chapter_stack_and_queue/array_queue.go +++ b/codes/go/chapter_stack_and_queue/array_queue.go @@ -56,7 +56,7 @@ func (q *ArrayQueue) Poll() any { return nil } v := q.data[q.head] - // 队头指针向后移动,越过尾部后返回到数组头部 + // 队头指针向后移动一位,若越过尾部则返回到数组头部 q.head = (q.head + 1) % q.capacity return v } diff --git a/codes/java/chapter_array_and_linkedlist/my_list.java b/codes/java/chapter_array_and_linkedlist/my_list.java index 74153b0..1f9fdc3 100644 --- a/codes/java/chapter_array_and_linkedlist/my_list.java +++ b/codes/java/chapter_array_and_linkedlist/my_list.java @@ -56,13 +56,13 @@ class MyList { } /* 中间插入元素 */ - public void add(int index, int num) { + public void insert(int index, int num) { if (index >= size) throw new IndexOutOfBoundsException("索引越界"); // 元素数量超出容量时,触发扩容机制 if (size == capacity()) extendCapacity(); - // 索引 i 以及之后的元素都向后移动一位 + // 将索引 index 以及之后的元素都向后移动一位 for (int j = size - 1; j >= index; j--) { nums[j + 1] = nums[j]; } @@ -72,15 +72,18 @@ class MyList { } /* 删除元素 */ - public void remove(int index) { + public int remove(int index) { if (index >= size) throw new IndexOutOfBoundsException("索引越界"); - // 索引 i 之后的元素都向前移动一位 + int num = nums[index]; + // 将索引 index 之后的元素都向前移动一位 for (int j = index; j < size - 1; j++) { nums[j] = nums[j + 1]; } // 更新元素数量 size--; + // 返回被删除元素 + return num; } /* 列表扩容 */ @@ -118,7 +121,7 @@ public class my_list { " ,容量 = " + list.capacity() + " ,长度 = " + list.size()); /* 中间插入元素 */ - list.add(3, 6); + list.insert(3, 6); System.out.println("在索引 3 处插入数字 6 ,得到 list = " + Arrays.toString(list.toArray())); /* 删除元素 */ diff --git a/codes/java/chapter_stack_and_queue/array_queue.java b/codes/java/chapter_stack_and_queue/array_queue.java index ff22559..620ce2d 100644 --- a/codes/java/chapter_stack_and_queue/array_queue.java +++ b/codes/java/chapter_stack_and_queue/array_queue.java @@ -50,11 +50,8 @@ class ArrayQueue { /* 出队 */ public int poll() { - // 删除头结点 - if (isEmpty()) - throw new EmptyStackException(); - int num = nums[front]; - // 队头指针向后移动,越过尾部后返回到数组头部 + int num = peek(); + // 队头指针向后移动一位,若越过尾部则返回到数组头部 front = (front + 1) % capacity(); return num; } diff --git a/codes/javascript/chapter_sorting/bubble_sort.js b/codes/javascript/chapter_sorting/bubble_sort.js index 270565c..3d3c6a8 100644 --- a/codes/javascript/chapter_sorting/bubble_sort.js +++ b/codes/javascript/chapter_sorting/bubble_sort.js @@ -46,4 +46,4 @@ console.log("排序后数组 nums =", nums) var nums1 = [4, 1, 3, 1, 5, 2] bubbleSortWithFlag(nums1) -console.log("排序后数组 nums =", nums1) \ No newline at end of file +console.log("排序后数组 nums =", nums1) diff --git a/codes/javascript/chapter_sorting/insertion_sort.js b/codes/javascript/chapter_sorting/insertion_sort.js index 2ba7155..9a6f119 100644 --- a/codes/javascript/chapter_sorting/insertion_sort.js +++ b/codes/javascript/chapter_sorting/insertion_sort.js @@ -21,4 +21,4 @@ function insertionSort(nums) { /* Driver Code */ var nums = [4, 1, 3, 1, 5, 2] insertionSort(nums) -console.log("排序后数组 nums = ", nums) \ No newline at end of file +console.log("排序后数组 nums = ", nums) diff --git a/codes/javascript/chapter_sorting/merge_sort.js b/codes/javascript/chapter_sorting/merge_sort.js index 635cc1d..d57e41a 100644 --- a/codes/javascript/chapter_sorting/merge_sort.js +++ b/codes/javascript/chapter_sorting/merge_sort.js @@ -48,4 +48,4 @@ function mergeSort(nums, left, right) { /* Driver Code */ var nums = [ 7, 3, 2, 6, 0, 1, 5, 4 ] mergeSort(nums, 0, nums.length - 1) -console.log("归并排序完成后 nums =", nums) \ No newline at end of file +console.log("归并排序完成后 nums =", nums) diff --git a/codes/python/chapter_array_and_linkedlist/my_list.py b/codes/python/chapter_array_and_linkedlist/my_list.py index 5d8997b..077fc0c 100644 --- a/codes/python/chapter_array_and_linkedlist/my_list.py +++ b/codes/python/chapter_array_and_linkedlist/my_list.py @@ -36,9 +36,10 @@ class MyList: assert index < self.__size, "索引越界" self.__nums[index] = num - """ 中间插入元素 """ + """ 中间插入(尾部添加)元素 """ def add(self, num, index=-1): assert index < self.__size, "索引越界" + # 若不指定索引 index ,则向数组尾部添加元素 if index == -1: index = self.__size # 元素数量超出容量时,触发扩容机制 diff --git a/codes/python/chapter_stack_and_queue/array_queue.py b/codes/python/chapter_stack_and_queue/array_queue.py index c4284d8..b848794 100644 --- a/codes/python/chapter_stack_and_queue/array_queue.py +++ b/codes/python/chapter_stack_and_queue/array_queue.py @@ -13,9 +13,9 @@ from include import * """ 基于环形数组实现的队列 """ class ArrayQueue: def __init__(self, size): - self.__nums = [None] * size # 用于存储队列元素的数组 - self.__front = 0 # 头指针,指向队首 - self.__rear = 0 # 尾指针,指向队尾 + 1 + self.__nums = [0] * size # 用于存储队列元素的数组 + self.__front = 0 # 头指针,指向队首 + self.__rear = 0 # 尾指针,指向队尾 + 1 """ 获取队列的容量 """ def capacity(self): @@ -31,7 +31,7 @@ class ArrayQueue: return (self.__rear - self.__front) == 0 """ 入队 """ - def put(self, val): + def push(self, val): if self.size() == self.capacity(): print("队列已满") return False @@ -41,13 +41,10 @@ class ArrayQueue: self.__rear = (self.__rear + 1) % self.capacity() """ 出队 """ - def get(self): + def poll(self): # 删除头结点 - if self.is_empty(): - print("队列为空") - return False - num = self.__nums[self.__front] - # 队头指针向后移动,越过尾部后返回到数组头部 + num = self.peek() + # 队头指针向后移动一位,若越过尾部则返回到数组头部 self.__front = (self.__front + 1) % self.capacity() return num @@ -60,7 +57,7 @@ class ArrayQueue: return self.__nums[self.__front] """ 访问指定位置元素 """ - def get_index(self, index): + def get(self, index): if index >= self.size(): print("索引越界") return False @@ -68,7 +65,7 @@ class ArrayQueue: """ 返回列表用于打印 """ def to_list(self): - res = [None] * self.size() + res = [0] * self.size() j = self.__front for i in range(self.size()): res[i] = self.__nums[(j % self.capacity())] @@ -76,35 +73,36 @@ class ArrayQueue: return res +""" Driver Code """ if __name__ == "__main__": """ 初始化队列 """ queue = ArrayQueue(10) """ 元素入队 """ - queue.put(1) - queue.put(3) - queue.put(2) - queue.put(5) - queue.put(4) - print("队列 queue = ", queue.to_list()) + queue.push(1) + queue.push(3) + queue.push(2) + queue.push(5) + queue.push(4) + print("队列 queue =", queue.to_list()) """ 访问队首元素 """ peek = queue.peek() - print("队首元素 peek = ", peek) + print("队首元素 peek =", peek) """ 访问索引 index 处元素 """ - num = queue.get_index(3) + num = queue.get(3) print("队列索引 3 处的元素为 num =", num) """ 元素出队 """ - get = queue.get() - print("出队元素 get = ", get) - print("出队后 queue = ", queue.to_list()) + poll = queue.poll() + print("出队元素 poll =", poll) + print("出队后 queue =", queue.to_list()) """ 获取队列的长度 """ size = queue.size() - print("队列长度 size = ", size) + print("队列长度 size =", size) """ 判断队列是否为空 """ is_empty = queue.is_empty() - print("队列是否为空 = ", is_empty) + print("队列是否为空 =", is_empty) diff --git a/codes/python/chapter_stack_and_queue/deque.py b/codes/python/chapter_stack_and_queue/deque.py index a2929df..8a68fe7 100644 --- a/codes/python/chapter_stack_and_queue/deque.py +++ b/codes/python/chapter_stack_and_queue/deque.py @@ -12,36 +12,38 @@ from include import * from collections import deque + +""" Driver Code """ if __name__ == "__main__": """ 初始化双向队列 """ duque = deque() """ 元素入队 """ - duque.append(2) # 添加至队尾 + duque.append(2) # 添加至队尾 duque.append(5) duque.append(4) duque.appendleft(3) # 添加至队首 duque.appendleft(1) - print("双向队列 duque = ", duque) + print("双向队列 duque =", duque) """ 访问队首元素 """ - peekFirst = duque[0] # 队首元素 - print("队首元素 peekFirst = ", peekFirst) - peekLast = duque[-1] # 队尾元素 - print("队尾元素 peekLast = ", peekLast) + front = duque[0] # 队首元素 + print("队首元素 front =", front) + rear = duque[-1] # 队尾元素 + print("队尾元素 rear =", rear) """ 元素出队 """ - popFirst = duque.pop() # 队首元素出队 - print("队首出队元素 popFirst= ", popFirst) - print("队首出队后 duque = ", duque) - popLast = duque.popleft() # 队尾元素出队 - print("队尾出队元素 popLast= ", popLast) - print("队尾出队后 duque = ", duque) + pop_front = duque.popleft() # 队首元素出队 + print("队首出队元素 pop_front =", pop_front) + print("队首出队后 duque =", duque) + pop_rear = duque.pop() # 队尾元素出队 + print("队尾出队元素 pop_rear =", pop_rear) + print("队尾出队后 duque =", duque) """ 获取双向队列的长度 """ size = len(duque) - print("双向队列长度 size = ", size) + print("双向队列长度 size =", size) """ 判断双向队列是否为空 """ is_empty = len(duque) == 0 - print("双向队列是否为空 = ", is_empty) + print("双向队列是否为空 =", is_empty) diff --git a/codes/python/chapter_stack_and_queue/linkedlist_queue.py b/codes/python/chapter_stack_and_queue/linkedlist_queue.py index d5a2202..0d4a28d 100644 --- a/codes/python/chapter_stack_and_queue/linkedlist_queue.py +++ b/codes/python/chapter_stack_and_queue/linkedlist_queue.py @@ -13,8 +13,8 @@ from include import * """ 基于链表实现的队列 """ class LinkedListQueue: def __init__(self): - self.__front = 0 # 头结点 front - self.__rear = 0 # 尾结点 rear + self.__front = None # 头结点 front + self.__rear = None # 尾结点 rear self.__size = 0 """ 获取队列的长度 """ @@ -26,7 +26,7 @@ class LinkedListQueue: return not self.__front """ 入队 """ - def put(self, num): + def push(self, num): # 尾结点后添加 num node = ListNode(num) # 如果队列为空,则令头、尾结点都指向该结点 @@ -40,7 +40,7 @@ class LinkedListQueue: self.__size += 1 """ 出队 """ - def get(self): + def poll(self): num = self.peek() # 删除头结点 self.__front = self.__front.next @@ -64,31 +64,32 @@ class LinkedListQueue: return queue +""" Driver Code """ if __name__ == "__main__": """ 初始化队列 """ queue = LinkedListQueue() """ 元素入队 """ - queue.put(1) - queue.put(3) - queue.put(2) - queue.put(5) - queue.put(4) - print("队列 queue = ", queue.to_list()) + queue.push(1) + queue.push(3) + queue.push(2) + queue.push(5) + queue.push(4) + print("队列 queue =", queue.to_list()) """ 访问队首元素 """ peek = queue.peek() - print("队首元素 front = ", peek) + print("队首元素 front =", peek) """ 元素出队 """ - get = queue.get() - print("出队元素 get = ", get) - print("出队后 queue = ", queue.to_list()) + pop_front = queue.poll() + print("出队元素 poll =", pop_front) + print("出队后 queue =", queue.to_list()) """ 获取队列的长度 """ size = queue.size() - print("队列长度 size = ", size) + print("队列长度 size =", size) """ 判断队列是否为空 """ is_empty = queue.is_empty() - print("队列是否为空 = ", is_empty) + print("队列是否为空 =", is_empty) diff --git a/codes/python/chapter_stack_and_queue/queue.py b/codes/python/chapter_stack_and_queue/queue.py index 3f39d2d..93729a8 100644 --- a/codes/python/chapter_stack_and_queue/queue.py +++ b/codes/python/chapter_stack_and_queue/queue.py @@ -1,5 +1,5 @@ ''' -File: queue.py +File: que.py Created Time: 2022-11-29 Author: Peng Chen (pengchzn@gmail.com) ''' @@ -10,33 +10,35 @@ import sys sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) from include import * -import queue -if __name__ == "__main__": +""" Driver Code """ +if __name__ == "__main__": """ 初始化队列 """ - queue = queue.Queue() + # 在 Python 中,我们一般将双向队列类 deque 看左队列使用 + # 虽然 queue.Queue() 是纯正的队列类,但不太好用,因此不建议 + que = collections.deque() """ 元素入队 """ - queue.put(1) - queue.put(3) - queue.put(2) - queue.put(5) - queue.put(4) - print("队列 queue = ", queue.queue) + que.append(1) + que.append(3) + que.append(2) + que.append(5) + que.append(4) + print("队列 que =", que) """ 访问队首元素 """ - peek = queue.queue[0] - print("队首元素 peek = ", peek) + front = que[0]; + print("队首元素 front =", front); """ 元素出队 """ - get = queue.get() - print("出队元素 get = ", get) - print("出队后 queue = ", queue.queue) + pop = que.popleft() + print("出队元素 pop =", pop) + print("出队后 que =", que) """ 获取队列的长度 """ - size = queue.qsize() - print("队列长度 size = ", size) + size = len(que) + print("队列长度 size =", size) """ 判断队列是否为空 """ - is_empty = queue.empty() - print("队列是否为空 = ", is_empty) + is_empty = len(que) == 0 + print("队列是否为空 =", is_empty) diff --git a/codes/python/include/__init__.py b/codes/python/include/__init__.py index 5939efb..77cf855 100644 --- a/codes/python/include/__init__.py +++ b/codes/python/include/__init__.py @@ -1,5 +1,6 @@ import copy import math +import queue import random import functools import collections diff --git a/codes/python/include/print_util.py b/codes/python/include/print_util.py index b7c2ba2..f315add 100644 --- a/codes/python/include/print_util.py +++ b/codes/python/include/print_util.py @@ -4,6 +4,8 @@ Created Time: 2021-12-11 Author: Krahets (krahets@163.com) ''' +import copy +import queue from .binary_tree import TreeNode, tree_to_list from .linked_list import ListNode, linked_list_to_list @@ -28,7 +30,6 @@ def print_linked_list(head): arr = linked_list_to_list(head) print(' -> '.join([str(a) for a in arr])) - class Trunk: def __init__(self, prev=None, str=None): self.prev = prev diff --git a/docs/chapter_array_and_linkedlist/list.md b/docs/chapter_array_and_linkedlist/list.md index 11dd816..db9bdbf 100644 --- a/docs/chapter_array_and_linkedlist/list.md +++ b/docs/chapter_array_and_linkedlist/list.md @@ -288,13 +288,13 @@ comments: true } /* 中间插入元素 */ - public void add(int index, int num) { + public void insert(int index, int num) { if (index >= size) throw new IndexOutOfBoundsException("索引越界"); // 元素数量超出容量时,触发扩容机制 if (size == capacity()) extendCapacity(); - // 索引 i 以及之后的元素都向后移动一位 + // 将索引 index 以及之后的元素都向后移动一位 for (int j = size - 1; j >= index; j--) { nums[j + 1] = nums[j]; } @@ -304,15 +304,18 @@ comments: true } /* 删除元素 */ - public void remove(int index) { + public int remove(int index) { if (index >= size) throw new IndexOutOfBoundsException("索引越界"); - // 索引 i 之后的元素都向前移动一位 + int num = nums[index]; + // 将索引 index 之后的元素都向前移动一位 for (int j = index; j < size - 1; j++) { nums[j] = nums[j + 1]; } // 更新元素数量 size--; + // 返回被删除元素 + return num; } /* 列表扩容 */ @@ -394,15 +397,18 @@ comments: true } /* 删除元素 */ - void remove(int index) { + int remove(int index) { if (index >= size()) throw out_of_range("索引越界"); + int num = nums[index]; // 索引 i 之后的元素都向前移动一位 for (int j = index; j < size() - 1; j++) { nums[j] = nums[j + 1]; } // 更新元素数量 numsSize--; + // 返回被删除元素 + return num; } /* 列表扩容 */ @@ -419,16 +425,6 @@ comments: true delete[] temp; numsCapacity = newCapacity; } - - /* 将列表转换为 Vector 用于打印 */ - vector toVector() { - // 仅转换有效长度范围内的列表元素 - vector vec(size()); - for (int i = 0; i < size(); i++) { - vec[i] = nums[i]; - } - return vec; - } }; ``` @@ -463,9 +459,10 @@ comments: true assert index < self.__size, "索引越界" self.__nums[index] = num - """ 中间插入元素 """ + """ 中间插入(尾部添加)元素 """ def add(self, num, index=-1): assert index < self.__size, "索引越界" + # 若不指定索引 index ,则向数组尾部添加元素 if index == -1: index = self.__size # 元素数量超出容量时,触发扩容机制 diff --git a/docs/chapter_stack_and_queue/deque.md b/docs/chapter_stack_and_queue/deque.md index 0665762..f9b45ec 100644 --- a/docs/chapter_stack_and_queue/deque.md +++ b/docs/chapter_stack_and_queue/deque.md @@ -92,5 +92,27 @@ comments: true === "Python" ```python title="deque.py" - + """ 初始化双向队列 """ + duque = deque() + + """ 元素入队 """ + duque.append(2) # 添加至队尾 + duque.append(5) + duque.append(4) + duque.appendleft(3) # 添加至队首 + duque.appendleft(1) + + """ 访问队首元素 """ + front = duque[0] # 队首元素 + rear = duque[-1] # 队尾元素 + + """ 元素出队 """ + pop_front = duque.popleft() # 队首元素出队 + pop_rear = duque.pop() # 队尾元素出队 + + """ 获取双向队列的长度 """ + size = len(duque) + + """ 判断双向队列是否为空 """ + is_empty = len(duque) == 0 ``` diff --git a/docs/chapter_stack_and_queue/queue.md b/docs/chapter_stack_and_queue/queue.md index f69f37e..825b58e 100644 --- a/docs/chapter_stack_and_queue/queue.md +++ b/docs/chapter_stack_and_queue/queue.md @@ -20,13 +20,13 @@ comments: true
-| 方法 | 描述 | -| --------- | ---------------------------- | -| offer() | 元素入队,即将元素添加至队尾 | -| poll() | 队首元素出队 | -| front() | 访问队首元素 | -| size() | 获取队列的长度 | -| isEmpty() | 判断队列是否为空 | +| 方法 | 描述 | +| --------- | ------------------------ | +| offer() | 元素入队,即将元素添加至队尾 | +| poll() | 队首元素出队 | +| front() | 访问队首元素 | +| size() | 获取队列的长度 | +| isEmpty() | 判断队列是否为空 |
@@ -87,7 +87,29 @@ comments: true === "Python" ```python title="queue.py" - + """ 初始化队列 """ + # 在 Python 中,我们一般将双向队列类 deque 看左队列使用 + # 虽然 queue.Queue() 是纯正的队列类,但不太好用,因此不建议 + que = collections.deque() + + """ 元素入队 """ + que.append(1) + que.append(3) + que.append(2) + que.append(5) + que.append(4) + + """ 访问队首元素 """ + front = que[0]; + + """ 元素出队 """ + pop = que.popleft() + + """ 获取队列的长度 """ + size = len(que) + + """ 判断队列是否为空 """ + is_empty = len(que) == 0 ``` ## 队列实现 @@ -209,7 +231,49 @@ comments: true === "Python" ```python title="linkedlist_queue.py" - + """ 基于链表实现的队列 """ + class LinkedListQueue: + def __init__(self): + self.__front = None # 头结点 front + self.__rear = None # 尾结点 rear + self.__size = 0 + + """ 获取队列的长度 """ + def size(self): + return self.__size + + """ 判断队列是否为空 """ + def is_empty(self): + return not self.__front + + """ 入队 """ + def push(self, num): + # 尾结点后添加 num + node = ListNode(num) + # 如果队列为空,则令头、尾结点都指向该结点 + if self.__front == 0: + self.__front = node + self.__rear = node + # 如果队列不为空,则将该结点添加到尾结点后 + else: + self.__rear.next = node + self.__rear = node + self.__size += 1 + + """ 出队 """ + def poll(self): + num = self.peek() + # 删除头结点 + self.__front = self.__front.next + self.__size -= 1 + return num + + """ 访问队首元素 """ + def peek(self): + if self.size() == 0: + print("队列为空") + return False + return self.__front.val ``` ### 基于数组的实现 @@ -262,11 +326,8 @@ comments: true } /* 出队 */ public int poll() { - // 删除头结点 - if (isEmpty()) - throw new EmptyStackException(); - int num = nums[front]; - // 队头指针向后移动,越过尾部后返回到数组头部 + int num = peek(); + // 队头指针向后移动一位,若越过尾部则返回到数组头部 front = (front + 1) % capacity(); return num; } @@ -329,11 +390,8 @@ comments: true } /* 出队 */ int poll() { - // 删除头结点 - if (empty()) - throw out_of_range("队列为空"); - int num = nums[front]; - // 队头指针向后移动,越过尾部后返回到数组头部 + int num = peek(); + // 队头指针向后移动一位,若越过尾部则返回到数组头部 front = (front + 1) % capacity(); return num; } @@ -356,11 +414,70 @@ comments: true === "Python" ```python title="array_queue.py" - + """ 基于环形数组实现的队列 """ + class ArrayQueue: + def __init__(self, size): + self.__nums = [0] * size # 用于存储队列元素的数组 + self.__front = 0 # 头指针,指向队首 + self.__rear = 0 # 尾指针,指向队尾 + 1 + + """ 获取队列的容量 """ + def capacity(self): + return len(self.__nums) + + """ 获取队列的长度 """ + def size(self): + # 由于将数组看作为环形,可能 rear < front ,因此需要取余数 + return (self.capacity() + self.__rear - self.__front) % self.capacity() + + """ 判断队列是否为空 """ + def is_empty(self): + return (self.__rear - self.__front) == 0 + + """ 入队 """ + def push(self, val): + if self.size() == self.capacity(): + print("队列已满") + return False + # 尾结点后添加 num + self.__nums[self.__rear] = val + # 尾指针向后移动一位,越过尾部后返回到数组头部 + self.__rear = (self.__rear + 1) % self.capacity() + + """ 出队 """ + def poll(self): + # 删除头结点 + num = self.peek() + # 队头指针向后移动一位,若越过尾部则返回到数组头部 + self.__front = (self.__front + 1) % self.capacity() + return num + + """ 访问队首元素 """ + def peek(self): + # 删除头结点 + if self.is_empty(): + print("队列为空") + return False + return self.__nums[self.__front] + + """ 访问指定位置元素 """ + def get(self, index): + if index >= self.size(): + print("索引越界") + return False + return self.__nums[(self.__front + index) % self.capacity()] + + """ 返回列表用于打印 """ + def to_list(self): + res = [0] * self.size() + j = self.__front + for i in range(self.size()): + res[i] = self.__nums[(j % self.capacity())] + j += 1 + return res ``` ## 队列典型应用 - **淘宝订单。** 购物者下单后,订单就被加入到队列之中,随后系统再根据顺序依次处理队列中的订单。在双十一时,在短时间内会产生海量的订单,如何处理「高并发」则是工程师们需要重点思考的问题。 - - **各种待办事项。** 例如打印机的任务队列、餐厅的出餐队列等等。