diff --git a/chapter_stack_and_queue/deque.md b/chapter_stack_and_queue/deque.md index bd5382637..b9f9b4c79 100644 --- a/chapter_stack_and_queue/deque.md +++ b/chapter_stack_and_queue/deque.md @@ -740,7 +740,135 @@ comments: true === "Swift" ```swift title="linkedlist_deque.swift" + /* 双向链表结点 */ + class ListNode { + var val: Int // 结点值 + var next: ListNode? // 后继结点引用(指针) + var prev: ListNode? // 前驱结点引用(指针) + init(val: Int) { + self.val = val + } + } + + /* 基于双向链表实现的双向队列 */ + class LinkedListDeque { + private var front: ListNode? // 头结点 front + private var rear: ListNode? // 尾结点 rear + private var queSize: Int // 双向队列的长度 + + init() { + queSize = 0 + } + + /* 获取双向队列的长度 */ + func size() -> Int { + queSize + } + + /* 判断双向队列是否为空 */ + func isEmpty() -> Bool { + size() == 0 + } + + /* 入队操作 */ + private func push(num: Int, isFront: Bool) { + let node = ListNode(val: num) + // 若链表为空,则令 front, rear 都指向 node + if isEmpty() { + front = node + rear = node + } + // 队首入队操作 + else if isFront { + // 将 node 添加至链表头部 + front?.prev = node + node.next = front + front = node // 更新头结点 + } + // 队尾入队操作 + else { + // 将 node 添加至链表尾部 + rear?.next = node + node.prev = rear + rear = node // 更新尾结点 + } + queSize += 1 // 更新队列长度 + } + + /* 队首入队 */ + func pushFirst(num: Int) { + push(num: num, isFront: true) + } + + /* 队尾入队 */ + func pushLast(num: Int) { + push(num: num, isFront: false) + } + + /* 出队操作 */ + private func poll(isFront: Bool) -> Int { + if isEmpty() { + fatalError("双向队列为空") + } + let val: Int + // 队首出队操作 + if isFront { + val = front!.val // 暂存头结点值 + // 删除头结点 + let fNext = front?.next + if fNext != nil { + fNext?.prev = nil + front?.next = nil + } + front = fNext // 更新头结点 + } + // 队尾出队操作 + else { + val = rear!.val // 暂存尾结点值 + // 删除尾结点 + let rPrev = rear?.prev + if rPrev != nil { + rPrev?.next = nil + rear?.prev = nil + } + rear = rPrev // 更新尾结点 + } + queSize -= 1 // 更新队列长度 + return val + } + + /* 队首出队 */ + func pollFirst() -> Int { + poll(isFront: true) + } + + /* 队尾出队 */ + func pollLast() -> Int { + poll(isFront: false) + } + + /* 访问队首元素 */ + func peekFirst() -> Int? { + isEmpty() ? nil : front?.val + } + + /* 访问队尾元素 */ + func peekLast() -> Int? { + isEmpty() ? nil : rear?.val + } + + /* 返回数组用于打印 */ + func toArray() -> [Int] { + var node = front + var res = Array(repeating: 0, count: size()) + for i in res.indices { + res[i] = node!.val + node = node?.next + } + return res + } + } ``` === "Zig" @@ -924,7 +1052,113 @@ comments: true === "Swift" ```swift title="array_deque.swift" + /* 基于环形数组实现的双向队列 */ + class ArrayDeque { + private var nums: [Int] // 用于存储双向队列元素的数组 + private var front: Int // 队首指针,指向队首元素 + private var queSize: Int // 双向队列长度 + /* 构造方法 */ + init(capacity: Int) { + nums = Array(repeating: 0, count: capacity) + front = 0 + queSize = 0 + } + + /* 获取双向队列的容量 */ + func capacity() -> Int { + nums.count + } + + /* 获取双向队列的长度 */ + func size() -> Int { + queSize + } + + /* 判断双向队列是否为空 */ + func isEmpty() -> Bool { + size() == 0 + } + + /* 计算环形数组索引 */ + private func index(i: Int) -> Int { + // 通过取余操作实现数组首尾相连 + // 当 i 越过数组尾部后,回到头部 + // 当 i 越过数组头部后,回到尾部 + (i + capacity()) % capacity() + } + + /* 队首入队 */ + func pushFirst(num: Int) { + if size() == capacity() { + print("双向队列已满") + return + } + // 队首指针向左移动一位 + // 通过取余操作,实现 front 越过数组头部后回到尾部 + front = index(i: front - 1) + // 将 num 添加至队首 + nums[front] = num + queSize += 1 + } + + /* 队尾入队 */ + func pushLast(num: Int) { + if size() == capacity() { + print("双向队列已满") + return + } + // 计算尾指针,指向队尾索引 + 1 + let rear = index(i: front + size()) + // 将 num 添加至队尾 + nums[rear] = num + queSize += 1 + } + + /* 队首出队 */ + func pollFirst() -> Int { + let num = peekFirst() + // 队首指针向后移动一位 + front = index(i: front + 1) + queSize -= 1 + return num + } + + /* 队尾出队 */ + func pollLast() -> Int { + let num = peekLast() + queSize -= 1 + return num + } + + /* 访问队首元素 */ + func peekFirst() -> Int { + if isEmpty() { + fatalError("双向队列为空") + } + return nums[front] + } + + /* 访问队尾元素 */ + func peekLast() -> Int { + if isEmpty() { + fatalError("双向队列为空") + } + // 计算尾元素索引 + let last = index(i: front + size() - 1) + return nums[last] + } + + /* 返回数组用于打印 */ + func toArray() -> [Int] { + // 仅转换有效长度范围内的列表元素 + var res = Array(repeating: 0, count: size()) + for (i, j) in sequence(first: (0, front), next: { $0 < self.size() - 1 ? ($0 + 1, $1 + 1) : nil }) { + res[i] = nums[index(i: j)] + } + return res + } + } ``` === "Zig"