pull/944/head
krahets 2 years ago
parent f6b9a75c8f
commit a2073d5f1a

@ -12,18 +12,18 @@ comments: true
## 5.3.1.   双向队列常用操作 ## 5.3.1.   双向队列常用操作
双向队列的常用操作见下表,方法名需根据语言来确定,此处以 Java 为例 双向队列的常用操作见下表,方法名需根据语言来确定。
<div class="center-table" markdown> <div class="center-table" markdown>
| 方法名 | 描述 | 时间复杂度 | | 方法名 | 描述 | 时间复杂度 |
| ------------ | ---------------- | ---------- | | ----------- | -------------- | ---------- |
| pushFirst() | 将元素添加至队首 | $O(1)$ | | pushFirst() | 将元素添加至队首 | $O(1)$ |
| pushLast() | 将元素添加至队尾 | $O(1)$ | | pushLast() | 将元素添加至队尾 | $O(1)$ |
| pollFirst() | 删除队首元素 | $O(1)$ | | popFirst() | 删除队首元素 | $O(1)$ |
| pollLast() | 删除队尾元素 | $O(1)$ | | popLast() | 删除队尾元素 | $O(1)$ |
| peekFirst() | 访问队首元素 | $O(1)$ | | peekFirst() | 访问队首元素 | $O(1)$ |
| peekLast() | 访问队尾元素 | $O(1)$ | | peekLast() | 访问队尾元素 | $O(1)$ |
</div> </div>
@ -47,8 +47,8 @@ comments: true
int peekLast = deque.peekLast(); // 队尾元素 int peekLast = deque.peekLast(); // 队尾元素
/* 元素出队 */ /* 元素出队 */
int pollFirst = deque.pollFirst(); // 队首元素出队 int popFirst = deque.pollFirst(); // 队首元素出队
int pollLast = deque.pollLast(); // 队尾元素出队 int popLast = deque.pollLast(); // 队尾元素出队
/* 获取双向队列的长度 */ /* 获取双向队列的长度 */
int size = deque.size(); int size = deque.size();
@ -272,9 +272,9 @@ comments: true
let peekLast = deque.last! // 队尾元素 let peekLast = deque.last! // 队尾元素
/* 元素出队 */ /* 元素出队 */
// 使用 Array 模拟时 pollFirst 的复杂度为 O(n) // 使用 Array 模拟时 popFirst 的复杂度为 O(n)
let pollFirst = deque.removeFirst() // 队首元素出队 let popFirst = deque.removeFirst() // 队首元素出队
let pollLast = deque.removeLast() // 队尾元素出队 let popLast = deque.removeLast() // 队尾元素出队
/* 获取双向队列的长度 */ /* 获取双向队列的长度 */
let size = deque.count let size = deque.count
@ -310,11 +310,11 @@ comments: true
=== "pushFirst()" === "pushFirst()"
![linkedlist_deque_push_first](deque.assets/linkedlist_deque_push_first.png) ![linkedlist_deque_push_first](deque.assets/linkedlist_deque_push_first.png)
=== "pollLast()" === "popLast()"
![linkedlist_deque_poll_last](deque.assets/linkedlist_deque_poll_last.png) ![linkedlist_deque_pop_last](deque.assets/linkedlist_deque_pop_last.png)
=== "pollFirst()" === "popFirst()"
![linkedlist_deque_poll_first](deque.assets/linkedlist_deque_poll_first.png) ![linkedlist_deque_pop_first](deque.assets/linkedlist_deque_pop_first.png)
以下是具体实现代码。 以下是具体实现代码。
@ -384,7 +384,7 @@ comments: true
} }
/* 出队操作 */ /* 出队操作 */
private Integer poll(boolean isFront) { private Integer pop(boolean isFront) {
// 若队列为空,直接返回 null // 若队列为空,直接返回 null
if (isEmpty()) if (isEmpty())
return null; return null;
@ -415,13 +415,13 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
public Integer pollFirst() { public Integer popFirst() {
return poll(true); return pop(true);
} }
/* 队尾出队 */ /* 队尾出队 */
public Integer pollLast() { public Integer popLast() {
return poll(false); return pop(false);
} }
/* 访问队首元素 */ /* 访问队首元素 */
@ -522,7 +522,7 @@ comments: true
} }
/* 出队操作 */ /* 出队操作 */
int poll(bool isFront) { int pop(bool isFront) {
// 若队列为空,直接返回 -1 // 若队列为空,直接返回 -1
if (isEmpty()) if (isEmpty())
return -1; return -1;
@ -553,13 +553,13 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
int pollFirst() { int popFirst() {
return poll(true); return pop(true);
} }
/* 队尾出队 */ /* 队尾出队 */
int pollLast() { int popLast() {
return poll(false); return pop(false);
} }
/* 访问队首元素 */ /* 访问队首元素 */
@ -640,7 +640,7 @@ comments: true
""" 队尾入队 """ """ 队尾入队 """
self.push(num, False) self.push(num, False)
def poll(self, is_front: bool) -> int: def pop(self, is_front: bool) -> int:
""" 出队操作 """ """ 出队操作 """
# 若队列为空,直接返回 None # 若队列为空,直接返回 None
if self.is_empty(): if self.is_empty():
@ -666,13 +666,13 @@ comments: true
self.__size -= 1 # 更新队列长度 self.__size -= 1 # 更新队列长度
return val return val
def poll_first(self) -> int: def pop_first(self) -> int:
""" 队首出队 """ """ 队首出队 """
return self.poll(True) return self.pop(True)
def poll_last(self) -> int: def pop_last(self) -> int:
""" 队尾出队 """ """ 队尾出队 """
return self.poll(False) return self.pop(False)
def peek_first(self) -> int: def peek_first(self) -> int:
""" 访问队首元素 """ """ 访问队首元素 """
@ -719,7 +719,7 @@ comments: true
} }
/* 队首元素出队 */ /* 队首元素出队 */
func (s *linkedListDeque) pollFirst() any { func (s *linkedListDeque) popFirst() any {
if s.isEmpty() { if s.isEmpty() {
return nil return nil
} }
@ -729,7 +729,7 @@ comments: true
} }
/* 队尾元素出队 */ /* 队尾元素出队 */
func (s *linkedListDeque) pollLast() any { func (s *linkedListDeque) popLast() any {
if s.isEmpty() { if s.isEmpty() {
return nil return nil
} }
@ -833,7 +833,7 @@ comments: true
} }
/* 队尾出队操作 */ /* 队尾出队操作 */
pollLast() { popLast() {
if (this.#queSize === 0) { if (this.#queSize === 0) {
return null; return null;
} }
@ -850,7 +850,7 @@ comments: true
} }
/* 队首出队操作 */ /* 队首出队操作 */
pollFirst() { popFirst() {
if (this.#queSize === 0) { if (this.#queSize === 0) {
return null; return null;
} }
@ -960,7 +960,7 @@ comments: true
} }
/* 队尾出队操作 */ /* 队尾出队操作 */
pollLast(): number { popLast(): number {
if (this.queSize === 0) { if (this.queSize === 0) {
return null; return null;
} }
@ -977,7 +977,7 @@ comments: true
} }
/* 队首出队操作 */ /* 队首出队操作 */
pollFirst(): number { popFirst(): number {
if (this.queSize === 0) { if (this.queSize === 0) {
return null; return null;
} }
@ -1112,7 +1112,7 @@ comments: true
} }
/* 出队操作 */ /* 出队操作 */
private func poll(isFront: Bool) -> Int { private func pop(isFront: Bool) -> Int {
if isEmpty() { if isEmpty() {
fatalError("双向队列为空") fatalError("双向队列为空")
} }
@ -1144,13 +1144,13 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
func pollFirst() -> Int { func popFirst() -> Int {
poll(isFront: true) pop(isFront: true)
} }
/* 队尾出队 */ /* 队尾出队 */
func pollLast() -> Int { func popLast() -> Int {
poll(isFront: false) pop(isFront: false)
} }
/* 访问队首元素 */ /* 访问队首元素 */
@ -1270,7 +1270,7 @@ comments: true
} }
// 出队操作 // 出队操作
pub fn poll(self: *Self, isFront: bool) T { pub fn pop(self: *Self, isFront: bool) T {
if (self.isEmpty()) @panic("双向队列为空"); if (self.isEmpty()) @panic("双向队列为空");
var val: T = undefined; var val: T = undefined;
// 队首出队操作 // 队首出队操作
@ -1299,13 +1299,13 @@ comments: true
} }
// 队首出队 // 队首出队
pub fn pollFirst(self: *Self) T { pub fn popFirst(self: *Self) T {
return self.poll(true); return self.pop(true);
} }
// 队尾出队 // 队尾出队
pub fn pollLast(self: *Self) T { pub fn popLast(self: *Self) T {
return self.poll(false); return self.pop(false);
} }
// 访问队首元素 // 访问队首元素
@ -1362,11 +1362,11 @@ comments: true
=== "pushFirst()" === "pushFirst()"
![array_deque_push_first](deque.assets/array_deque_push_first.png) ![array_deque_push_first](deque.assets/array_deque_push_first.png)
=== "pollLast()" === "popLast()"
![array_deque_poll_last](deque.assets/array_deque_poll_last.png) ![array_deque_pop_last](deque.assets/array_deque_pop_last.png)
=== "pollFirst()" === "popFirst()"
![array_deque_poll_first](deque.assets/array_deque_poll_first.png) ![array_deque_pop_first](deque.assets/array_deque_pop_first.png)
以下是具体实现代码。 以下是具体实现代码。
@ -1436,7 +1436,7 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
public int pollFirst() { public int popFirst() {
int num = peekFirst(); int num = peekFirst();
// 队首指针向后移动一位 // 队首指针向后移动一位
front = index(front + 1); front = index(front + 1);
@ -1445,7 +1445,7 @@ comments: true
} }
/* 队尾出队 */ /* 队尾出队 */
public int pollLast() { public int popLast() {
int num = peekLast(); int num = peekLast();
queSize--; queSize--;
return num; return num;
@ -1547,7 +1547,7 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
int pollFirst() { int popFirst() {
int num = peekFirst(); int num = peekFirst();
// 队首指针向后移动一位 // 队首指针向后移动一位
front = index(front + 1); front = index(front + 1);
@ -1556,7 +1556,7 @@ comments: true
} }
/* 队尾出队 */ /* 队尾出队 */
int pollLast() { int popLast() {
int num = peekLast(); int num = peekLast();
queSize--; queSize--;
return num; return num;
@ -1644,7 +1644,7 @@ comments: true
self.__nums[rear] = num self.__nums[rear] = num
self.__size += 1 self.__size += 1
def poll_first(self) -> int: def pop_first(self) -> int:
""" 队首出队 """ """ 队首出队 """
num = self.peek_first() num = self.peek_first()
# 队首指针向后移动一位 # 队首指针向后移动一位
@ -1652,7 +1652,7 @@ comments: true
self.__size -= 1 self.__size -= 1
return num return num
def poll_last(self) -> int: def pop_last(self) -> int:
""" 队尾出队 """ """ 队尾出队 """
num = self.peek_last() num = self.peek_last()
self.__size -= 1 self.__size -= 1
@ -1752,7 +1752,7 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
pollFirst() { popFirst() {
const num = this.peekFirst(); const num = this.peekFirst();
// 队首指针向后移动一位 // 队首指针向后移动一位
this.#front = this.index(this.#front + 1); this.#front = this.index(this.#front + 1);
@ -1761,7 +1761,7 @@ comments: true
} }
/* 队尾出队 */ /* 队尾出队 */
pollLast() { popLast() {
const num = this.peekLast(); const num = this.peekLast();
this.#queSize--; this.#queSize--;
return num; return num;
@ -1862,7 +1862,7 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
pollFirst(): number { popFirst(): number {
const num: number = this.peekFirst(); const num: number = this.peekFirst();
// 队首指针向后移动一位 // 队首指针向后移动一位
this.front = this.index(this.front + 1); this.front = this.index(this.front + 1);
@ -1871,7 +1871,7 @@ comments: true
} }
/* 队尾出队 */ /* 队尾出队 */
pollLast(): number { popLast(): number {
const num: number = this.peekLast(); const num: number = this.peekLast();
this.queSize--; this.queSize--;
return num; return num;
@ -1984,7 +1984,7 @@ comments: true
} }
/* 队首出队 */ /* 队首出队 */
func pollFirst() -> Int { func popFirst() -> Int {
let num = peekFirst() let num = peekFirst()
// 队首指针向后移动一位 // 队首指针向后移动一位
front = index(i: front + 1) front = index(i: front + 1)
@ -1993,7 +1993,7 @@ comments: true
} }
/* 队尾出队 */ /* 队尾出队 */
func pollLast() -> Int { func popLast() -> Int {
let num = peekLast() let num = peekLast()
queSize -= 1 queSize -= 1
return num return num

@ -14,15 +14,15 @@ comments: true
## 5.2.1. &nbsp; 队列常用操作 ## 5.2.1. &nbsp; 队列常用操作
队列的常用操作见下表,方法名需根据语言来确定,此处以 Java 为例 队列的常用操作见下表。需要注意,不同编程语言的方法名是不同的,在这里我们采用与栈相同的方法命名
<div class="center-table" markdown> <div class="center-table" markdown>
| 方法名 | 描述 | 时间复杂度 | | 方法名 | 描述 | 时间复杂度 |
| --------- | -------------------------- | -------- | | --------- | -------------------------- | -------- |
| push() | 元素入队,即将元素添加至队尾 | $O(1)$ | | push() | 元素入队,即将元素添加至队尾 | $O(1)$ |
| poll() | 队首元素出队 | $O(1)$ | | pop() | 队首元素出队 | $O(1)$ |
| peek() | 访问队首元素 | $O(1)$ | | peek() | 访问队首元素 | $O(1)$ |
</div> </div>
@ -45,7 +45,7 @@ comments: true
int peek = queue.peek(); int peek = queue.peek();
/* 元素出队 */ /* 元素出队 */
int poll = queue.poll(); int pop = queue.poll();
/* 获取队列的长度 */ /* 获取队列的长度 */
int size = queue.size(); int size = queue.size();
@ -126,8 +126,8 @@ comments: true
peek := queue.Front() peek := queue.Front()
/* 元素出队 */ /* 元素出队 */
poll := queue.Front() pop := queue.Front()
queue.Remove(poll) queue.Remove(pop)
/* 获取队列的长度 */ /* 获取队列的长度 */
size := queue.Len() size := queue.Len()
@ -155,7 +155,7 @@ comments: true
/* 元素出队 */ /* 元素出队 */
// 底层是数组,因此 shift() 方法的时间复杂度为 O(n) // 底层是数组,因此 shift() 方法的时间复杂度为 O(n)
const poll = queue.shift(); const pop = queue.shift();
/* 获取队列的长度 */ /* 获取队列的长度 */
const size = queue.length; const size = queue.length;
@ -183,7 +183,7 @@ comments: true
/* 元素出队 */ /* 元素出队 */
// 底层是数组,因此 shift() 方法的时间复杂度为 O(n) // 底层是数组,因此 shift() 方法的时间复杂度为 O(n)
const poll = queue.shift(); const pop = queue.shift();
/* 获取队列的长度 */ /* 获取队列的长度 */
const size = queue.length; const size = queue.length;
@ -215,7 +215,7 @@ comments: true
int peek = queue.Peek(); int peek = queue.Peek();
/* 元素出队 */ /* 元素出队 */
int poll = queue.Dequeue(); int pop = queue.Dequeue();
/* 获取队列的长度 */ /* 获取队列的长度 */
int size = queue.Count(); int size = queue.Count();
@ -242,7 +242,7 @@ comments: true
let peek = queue.first! let peek = queue.first!
/* 元素出队 */ /* 元素出队 */
// 使用 Array 模拟时 poll 的复杂度为 O(n) // 由于是数组,因此 removeFirst 的复杂度为 O(n)
let pool = queue.removeFirst() let pool = queue.removeFirst()
/* 获取队列的长度 */ /* 获取队列的长度 */
@ -272,8 +272,8 @@ comments: true
=== "push()" === "push()"
![linkedlist_queue_push](queue.assets/linkedlist_queue_push.png) ![linkedlist_queue_push](queue.assets/linkedlist_queue_push.png)
=== "poll()" === "pop()"
![linkedlist_queue_poll](queue.assets/linkedlist_queue_poll.png) ![linkedlist_queue_pop](queue.assets/linkedlist_queue_pop.png)
以下是使用链表实现队列的示例代码。 以下是使用链表实现队列的示例代码。
@ -317,7 +317,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
public int poll() { public int pop() {
int num = peek(); int num = peek();
// 删除头结点 // 删除头结点
front = front.next; front = front.next;
@ -394,7 +394,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
void poll() { void pop() {
int num = peek(); int num = peek();
// 删除头结点 // 删除头结点
ListNode *tmp = front; ListNode *tmp = front;
@ -457,7 +457,7 @@ comments: true
self.__rear = node self.__rear = node
self.__size += 1 self.__size += 1
def poll(self) -> int: def pop(self) -> int:
""" 出队 """ """ 出队 """
num = self.peek() num = self.peek()
# 删除头结点 # 删除头结点
@ -504,7 +504,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
func (s *linkedListQueue) poll() any { func (s *linkedListQueue) pop() any {
if s.isEmpty() { if s.isEmpty() {
return nil return nil
} }
@ -579,7 +579,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
poll() { pop() {
const num = this.peek(); const num = this.peek();
// 删除头结点 // 删除头结点
this.#front = this.#front.next; this.#front = this.#front.next;
@ -648,7 +648,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
poll(): number { pop(): number {
const num = this.peek(); const num = this.peek();
if (!this.front) throw new Error('队列为空'); if (!this.front) throw new Error('队列为空');
// 删除头结点 // 删除头结点
@ -730,7 +730,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
public int poll() public int pop()
{ {
int num = peek(); int num = peek();
// 删除头结点 // 删除头结点
@ -805,7 +805,7 @@ comments: true
/* 出队 */ /* 出队 */
@discardableResult @discardableResult
func poll() -> Int { func pop() -> Int {
let num = peek() let num = peek()
// 删除头结点 // 删除头结点
front = front?.next front = front?.next
@ -899,7 +899,7 @@ comments: true
} }
// 出队 // 出队
pub fn poll(self: *Self) T { pub fn pop(self: *Self) T {
var num = self.peek(); var num = self.peek();
// 删除头结点 // 删除头结点
self.front = self.front.?.next; self.front = self.front.?.next;
@ -942,8 +942,8 @@ comments: true
=== "push()" === "push()"
![array_queue_push](queue.assets/array_queue_push.png) ![array_queue_push](queue.assets/array_queue_push.png)
=== "poll()" === "pop()"
![array_queue_poll](queue.assets/array_queue_poll.png) ![array_queue_pop](queue.assets/array_queue_pop.png)
细心的同学可能会发现一个问题:在不断入队与出队的过程中,`front` 和 `rear` 都在向右移动,**在到达数组尾部后就无法继续移动了**。为解决此问题,**我们考虑将数组看作是首尾相接的**,这样的数组被称为「环形数组」。 细心的同学可能会发现一个问题:在不断入队与出队的过程中,`front` 和 `rear` 都在向右移动,**在到达数组尾部后就无法继续移动了**。为解决此问题,**我们考虑将数组看作是首尾相接的**,这样的数组被称为「环形数组」。
@ -993,7 +993,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
public int poll() { public int pop() {
int num = peek(); int num = peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
front = (front + 1) % capacity(); front = (front + 1) % capacity();
@ -1073,7 +1073,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
void poll() { void pop() {
int num = peek(); int num = peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
front = (front + 1) % queCapacity; front = (front + 1) % queCapacity;
@ -1132,7 +1132,7 @@ comments: true
self.__nums[rear] = num self.__nums[rear] = num
self.__size += 1 self.__size += 1
def poll(self) -> int: def pop(self) -> int:
""" 出队 """ """ 出队 """
num: int = self.peek() num: int = self.peek()
# 队首指针向后移动一位,若越过尾部则返回到数组头部 # 队首指针向后移动一位,若越过尾部则返回到数组头部
@ -1201,7 +1201,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
func (q *arrayQueue) poll() any { func (q *arrayQueue) pop() any {
num := q.peek() num := q.peek()
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
q.front = (q.front + 1) % q.queCapacity q.front = (q.front + 1) % q.queCapacity
@ -1271,7 +1271,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
poll() { pop() {
const num = this.peek(); const num = this.peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
this.#front = (this.#front + 1) % this.capacity; this.#front = (this.#front + 1) % this.capacity;
@ -1342,7 +1342,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
poll(): number { pop(): number {
const num = this.peek(); const num = this.peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
this.front = (this.front + 1) % this.capacity; this.front = (this.front + 1) % this.capacity;
@ -1426,7 +1426,7 @@ comments: true
} }
/* 出队 */ /* 出队 */
public int poll() public int pop()
{ {
int num = peek(); int num = peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
@ -1502,7 +1502,7 @@ comments: true
/* 出队 */ /* 出队 */
@discardableResult @discardableResult
func poll() -> Int { func pop() -> Int {
let num = peek() let num = peek()
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
front = (front + 1) % capacity() front = (front + 1) % capacity()
@ -1592,7 +1592,7 @@ comments: true
} }
// 出队 // 出队
pub fn poll(self: *Self) T { pub fn pop(self: *Self) T {
var num = self.peek(); var num = self.peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部 // 队首指针向后移动一位,若越过尾部则返回到数组头部
self.front = (self.front + 1) % self.capacity(); self.front = (self.front + 1) % self.capacity();

@ -16,7 +16,7 @@ comments: true
## 5.1.1. &nbsp; 栈常用操作 ## 5.1.1. &nbsp; 栈常用操作
栈的常用操作见下表,方法名需根据语言来确定,此处以 Java 为例。 栈的常用操作见下表,方法名需根据编程语言来确定,此处我们以常见的 `push` , `pop` , `peek` 为例。
<div class="center-table" markdown> <div class="center-table" markdown>

Loading…
Cancel
Save