From 8669e064144236e44ba81369d6ae8542b46686ac Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Wed, 30 Nov 2022 02:27:26 +0800 Subject: [PATCH] Update stack and queue. --- .../chapter_array_and_linkedlist/my_list.cpp | 8 +- .../chapter_stack_and_queue/array_queue.cpp | 116 ++++++++ .../chapter_stack_and_queue/array_stack.cpp | 28 +- codes/cpp/chapter_stack_and_queue/deque.cpp | 39 +++ .../linkedlist_queue.cpp | 94 +++++++ .../linkedlist_stack.cpp | 53 ++-- codes/cpp/chapter_stack_and_queue/queue.cpp | 3 +- codes/cpp/chapter_stack_and_queue/stack.cpp | 1 + codes/cpp/include/PrintUtil.hpp | 22 +- .../chapter_stack_and_queue/array_queue.java | 10 +- .../chapter_stack_and_queue/array_stack.java | 17 +- codes/java/chapter_stack_and_queue/deque.java | 11 +- .../linkedlist_queue.java | 1 + .../linkedlist_stack.java | 37 ++- codes/java/chapter_stack_and_queue/queue.java | 1 + codes/java/chapter_stack_and_queue/stack.java | 18 +- .../chapter_array_and_linkedlist/my_list.py | 50 ++-- .../chapter_stack_and_queue/array_stack.py | 9 +- .../linkedlist_stack.py | 23 +- codes/python/chapter_stack_and_queue/stack.py | 3 +- docs/chapter_array_and_linkedlist/list.md | 56 ++-- docs/chapter_stack_and_queue/deque.md | 25 +- docs/chapter_stack_and_queue/queue.md | 8 +- docs/chapter_stack_and_queue/stack.md | 258 ++++++++++++++++-- 24 files changed, 705 insertions(+), 186 deletions(-) diff --git a/codes/cpp/chapter_array_and_linkedlist/my_list.cpp b/codes/cpp/chapter_array_and_linkedlist/my_list.cpp index 5c530dd..48d0cdb 100644 --- a/codes/cpp/chapter_array_and_linkedlist/my_list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/my_list.cpp @@ -34,14 +34,14 @@ public: int get(int index) { // 索引如果越界则抛出异常,下同 if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); return nums[index]; } /* 更新元素 */ void set(int index, int num) { if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); nums[index] = num; } @@ -58,7 +58,7 @@ public: /* 中间插入元素 */ void insert(int index, int num) { if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); // 元素数量超出容量时,触发扩容机制 if (size() == capacity()) extendCapacity(); @@ -74,7 +74,7 @@ public: /* 删除元素 */ void remove(int index) { if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); // 索引 i 之后的元素都向前移动一位 for (int j = index; j < size() - 1; j++) { nums[j] = nums[j + 1]; diff --git a/codes/cpp/chapter_stack_and_queue/array_queue.cpp b/codes/cpp/chapter_stack_and_queue/array_queue.cpp index ac10cd5..0aea80b 100644 --- a/codes/cpp/chapter_stack_and_queue/array_queue.cpp +++ b/codes/cpp/chapter_stack_and_queue/array_queue.cpp @@ -6,3 +6,119 @@ #include "../include/include.hpp" +/* 基于环形数组实现的队列 */ +class ArrayQueue { +private: + vector nums; // 用于存储队列元素的数组 + int front = 0; // 头指针,指向队首 + int rear = 0; // 尾指针,指向队尾 + 1 + +public: + ArrayQueue(int capacity) { + // 初始化数组 + nums.resize(capacity); + } + + /* 获取队列的容量 */ + int capacity() { + return nums.size(); + } + + /* 获取队列的长度 */ + int size() { + int cap = capacity(); + // 由于将数组看作为环形,可能 rear < front ,因此需要取余数 + return (cap + rear - front) % cap; + } + + /* 判断队列是否为空 */ + bool empty() { + return rear - front == 0; + } + + /* 入队 */ + void offer(int num) { + if (size() == capacity()) { + cout << "队列已满" << endl; + return; + } + // 尾结点后添加 num + nums[rear] = num; + // 尾指针向后移动一位,越过尾部后返回到数组头部 + rear = (rear + 1) % capacity(); + } + + /* 出队 */ + int poll() { + // 删除头结点 + if (empty()) + throw out_of_range("队列为空"); + int num = nums[front]; + // 队头指针向后移动,越过尾部后返回到数组头部 + front = (front + 1) % capacity(); + return num; + } + + /* 访问队首元素 */ + int peek() { + // 删除头结点 + if (empty()) + throw out_of_range("队列为空"); + return nums[front]; + } + + vector toVector() { + int siz = size(); + int cap = capacity(); + // 仅转换有效长度范围内的列表元素 + vector arr(siz); + for (int i = 0, j = front; i < siz; i++, j++) { + arr[i] = nums[j % cap]; + } + return arr; + } +}; + + +/* Driver Code */ +int main() { + /* 初始化队列 */ + int capacity = 10; + ArrayQueue* queue = new ArrayQueue(capacity); + + /* 元素入队 */ + queue->offer(1); + queue->offer(3); + queue->offer(2); + queue->offer(5); + queue->offer(4); + cout << "队列 queue = "; + PrintUtil::printVector(queue->toVector()); + + /* 访问队首元素 */ + int peek = queue->peek(); + cout << "队首元素 peek = " << peek << endl; + + /* 元素出队 */ + int poll = queue->poll(); + cout << "出队元素 poll = " << poll << ",出队后 queue = "; + PrintUtil::printVector(queue->toVector()); + + /* 获取队列的长度 */ + int size = queue->size(); + cout << "队列长度 size = " << size << endl; + + /* 判断队列是否为空 */ + bool empty = queue->empty(); + cout << "队列是否为空 = " << empty << endl; + + /* 测试环形数组 */ + for (int i = 0; i < 10; i++) { + queue->offer(i); + queue->poll(); + cout << "第 " << i << " 轮入队 + 出队后 queue = "; + PrintUtil::printVector(queue->toVector()); + } + + return 0; +} diff --git a/codes/cpp/chapter_stack_and_queue/array_stack.cpp b/codes/cpp/chapter_stack_and_queue/array_stack.cpp index 8b08e17..ccc1cb9 100644 --- a/codes/cpp/chapter_stack_and_queue/array_stack.cpp +++ b/codes/cpp/chapter_stack_and_queue/array_stack.cpp @@ -9,38 +9,44 @@ /* 基于数组实现的栈 */ class ArrayStack { private: - vector vec; + vector stack; + public: /* 获取栈的长度 */ int size() { - return vec.size(); + return stack.size(); } /* 判断栈是否为空 */ bool empty() { - return vec.empty(); + return stack.empty(); } /* 入栈 */ void push(int num) { - vec.push_back(num); + stack.push_back(num); } /* 出栈 */ int pop() { - int oldTop = vec.back(); - vec.pop_back(); + int oldTop = stack.back(); + stack.pop_back(); return oldTop; } /* 访问栈顶元素 */ int top() { - return vec.back(); + return stack.back(); + } + + /* 访问索引 index 处元素 */ + int get(int index) { + return stack[index]; } /* 返回 Vector */ vector toVector() { - return vec; + return stack; } }; @@ -57,8 +63,7 @@ int main() { stack->push(5); stack->push(4); cout << "栈 stack = "; - vector vec = stack->toVector(); - PrintUtil::printVector(vec); + PrintUtil::printVector(stack->toVector()); /* 访问栈顶元素 */ int top = stack->top(); @@ -67,8 +72,7 @@ int main() { /* 元素出栈 */ int pop = stack->pop(); cout << "出栈元素 pop = " << pop << ",出栈后 stack = "; - vec = stack->toVector(); - PrintUtil::printVector(vec); + PrintUtil::printVector(stack->toVector()); /* 获取栈的长度 */ int size = stack->size(); diff --git a/codes/cpp/chapter_stack_and_queue/deque.cpp b/codes/cpp/chapter_stack_and_queue/deque.cpp index cb777e8..820dd4a 100644 --- a/codes/cpp/chapter_stack_and_queue/deque.cpp +++ b/codes/cpp/chapter_stack_and_queue/deque.cpp @@ -6,3 +6,42 @@ #include "../include/include.hpp" + +/* Driver Code */ +int main() { + /* 初始化双向队列 */ + deque deque; + + /* 元素入队 */ + deque.push_back(2); + deque.push_back(5); + deque.push_back(4); + deque.push_front(3); + deque.push_front(1); + cout << "双向队列 deque = "; + PrintUtil::printDeque(deque); + + /* 访问队首元素 */ + int front = deque.front(); + cout << "队首元素 front = " << front << endl; + int back = deque.back(); + cout << "队尾元素 back = " << back << endl; + + /* 元素出队 */ + deque.pop_front(); + cout << "队首出队元素 popFront = " << front << ",队首出队后 deque = "; + PrintUtil::printDeque(deque); + deque.pop_back(); + cout << "队尾出队元素 popLast = " << back << ",队尾出队后 deque = "; + PrintUtil::printDeque(deque); + + /* 获取双向队列的长度 */ + int size = deque.size(); + cout << "双向队列长度 size = " << size << endl; + + /* 判断双向队列是否为空 */ + bool empty = deque.empty(); + cout << "双向队列是否为空 = " << empty << endl; + + return 0; +} diff --git a/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp b/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp index 5c24229..d3cb35b 100644 --- a/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp +++ b/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp @@ -6,3 +6,97 @@ #include "../include/include.hpp" +/* 基于链表实现的队列 */ +class LinkedListQueue { +private: + ListNode *front, *back; + int qSize; + +public: + LinkedListQueue() { + front = nullptr; + back = nullptr; + qSize = 0; + } + + /* 获取队列的长度 */ + int size() { + return qSize; + } + + /* 判断队列是否为空 */ + bool empty() { + return qSize == 0; + } + + /* 入队 */ + void offer(int num) { + // 尾结点后添加 num + ListNode* node = new ListNode(num); + node->next = back; + back = node; + qSize++; + } + + /* 出队 */ + int poll() { + if (qSize == 0) + throw out_of_range("队列为空"); + // 删除头结点 + ListNode* node = front; + front = front->next; + return node->val; + } + + /* 访问队首元素 */ + int peek() { + return front->val; + } + + /* 将 List 转化为 Array 并返回 */ + vector toVector() { + ListNode* node = front; + vector vec; + while (node != nullptr) { + vec.push_back(node->val); + node = node->next; + } + reverse(vec.begin(), vec.end()); + return vec; + } +}; + + +/* Driver Code */ +int main() { + /* 初始化队列 */ + LinkedListQueue* queue = new LinkedListQueue(); + + /* 元素入队 */ + queue->offer(1); + queue->offer(3); + queue->offer(2); + queue->offer(5); + queue->offer(4); + cout << "队列 queue = "; + PrintUtil::printVector(queue->toVector()); + + /* 访问队首元素 */ + int peek = queue->peek(); + cout << "队首元素 peek = " << peek << endl; + + /* 元素出队 */ + int poll = queue->poll(); + cout << "出队元素 poll = " << poll << ",出队后 queue = "; + PrintUtil::printVector(queue->toVector()); + + /* 获取队列的长度 */ + int size = queue->size(); + cout << "队列长度 size = " << size << endl; + + /* 判断队列是否为空 */ + bool empty = queue->empty(); + cout << "队列是否为空 = " << empty << endl; + + return 0; +} diff --git a/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp b/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp index 15eec80..1ffae5e 100644 --- a/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp +++ b/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp @@ -9,38 +9,59 @@ /* 基于链表实现的栈 */ class LinkedListStack { private: - list list; + ListNode* stackTop; // 将头结点作为栈顶 + int stackSize; // 栈的长度 + public: + LinkedListStack() { + stackTop = nullptr; + stackSize = 0; + } + /* 获取栈的长度 */ int size() { - return list.size(); + return stackSize; } + /* 判断栈是否为空 */ bool empty() { - return list.empty(); + return size() == 0; } + /* 入栈 */ void push(int num) { - list.push_back(num); + ListNode* node = new ListNode(num); + node->next = stackTop; + stackTop = node; + stackSize++; } + /* 出栈 */ int pop() { - int oldTop = list.back(); - list.pop_back(); - return oldTop; + if (size() == 0) + throw out_of_range("栈为空"); + int num = stackTop->val; + stackTop = stackTop->next; + stackSize--; + return num; } + /* 访问栈顶元素 */ int top() { - return list.back(); + if (size() == 0) + throw out_of_range("栈为空"); + return stackTop->val; } /* 将 List 转化为 Array 并返回 */ vector toVector() { - vector vec; - for (int num : list) { - vec.push_back(num); + ListNode* node = stackTop; + vector res(size()); + for (int i = res.size() - 1; i >= 0; i--) { + res[i] = node->val; + node = node->next; } - return vec; + return res; } }; @@ -57,8 +78,7 @@ int main() { stack->push(5); stack->push(4); cout << "栈 stack = "; - vector vec = stack->toVector(); - PrintUtil::printVector(vec); + PrintUtil::printVector(stack->toVector()); /* 访问栈顶元素 */ int top = stack->top(); @@ -67,8 +87,7 @@ int main() { /* 元素出栈 */ int pop = stack->pop(); cout << "出栈元素 pop = " << pop << ",出栈后 stack = "; - vec = stack->toVector(); - PrintUtil::printVector(vec); + PrintUtil::printVector(stack->toVector()); /* 获取栈的长度 */ int size = stack->size(); @@ -77,4 +96,6 @@ int main() { /* 判断是否为空 */ bool empty = stack->empty(); cout << "栈是否为空 = " << empty << endl; + + return 0; } diff --git a/codes/cpp/chapter_stack_and_queue/queue.cpp b/codes/cpp/chapter_stack_and_queue/queue.cpp index ccaefb1..2ca504a 100644 --- a/codes/cpp/chapter_stack_and_queue/queue.cpp +++ b/codes/cpp/chapter_stack_and_queue/queue.cpp @@ -35,7 +35,8 @@ int main(){ cout << "队列长度 size = " << size << endl; /* 判断队列是否为空 */ - bool isEmpty = queue.empty(); + bool empty = queue.empty(); + cout << "队列是否为空 = " << empty << endl; return 0; } diff --git a/codes/cpp/chapter_stack_and_queue/stack.cpp b/codes/cpp/chapter_stack_and_queue/stack.cpp index 91cff94..cc02769 100644 --- a/codes/cpp/chapter_stack_and_queue/stack.cpp +++ b/codes/cpp/chapter_stack_and_queue/stack.cpp @@ -36,6 +36,7 @@ int main() { /* 判断是否为空 */ bool empty = stack.empty(); + cout << "栈是否为空 = " << empty << endl; return 0; } diff --git a/codes/cpp/include/PrintUtil.hpp b/codes/cpp/include/PrintUtil.hpp index 06f2f63..772eb9b 100644 --- a/codes/cpp/include/PrintUtil.hpp +++ b/codes/cpp/include/PrintUtil.hpp @@ -102,7 +102,7 @@ class PrintUtil { * @param list */ template - static void printVector(vector &list) { + static void printVector(vector list) { cout << getVectorString(list) << '\n'; } @@ -218,7 +218,7 @@ class PrintUtil { * @param stk */ template - static void printStack(stack &stk) { + static void printStack(stack stk) { // Reverse the input stack stack tmp; while(!stk.empty()) { @@ -246,7 +246,7 @@ class PrintUtil { * @param queue */ template - static void printQueue(queue &queue) + static void printQueue(queue queue) { // Generate the string to print ostringstream s; @@ -261,4 +261,20 @@ class PrintUtil { } cout << "[" + s.str() + "]" << '\n'; } + + template + static void printDeque(deque deque) { + // Generate the string to print + ostringstream s; + bool flag = true; + while(!deque.empty()) { + if (flag) { + s << deque.front(); + flag = false; + } + else s << ", " << deque.front(); + deque.pop_front(); + } + cout << "[" + s.str() + "]" << '\n'; + } }; diff --git a/codes/java/chapter_stack_and_queue/array_queue.java b/codes/java/chapter_stack_and_queue/array_queue.java index 251e7ac..aab3154 100644 --- a/codes/java/chapter_stack_and_queue/array_queue.java +++ b/codes/java/chapter_stack_and_queue/array_queue.java @@ -10,10 +10,9 @@ import java.util.*; /* 基于环形数组实现的队列 */ class ArrayQueue { - int[] nums; // 用于存储队列元素的数组 - int size = 0; // 队列长度(即元素个数) - int front = 0; // 头指针,指向队首 - int rear = 0; // 尾指针,指向队尾 + 1 + private int[] nums; // 用于存储队列元素的数组 + private int front = 0; // 头指针,指向队首 + private int rear = 0; // 尾指针,指向队尾 + 1 public ArrayQueue(int capacity) { // 初始化数组 @@ -108,12 +107,13 @@ public class array_queue { /* 判断队列是否为空 */ boolean isEmpty = queue.isEmpty(); + System.out.println("队列是否为空 = " + isEmpty); /* 测试环形数组 */ for (int i = 0; i < 10; i++) { queue.offer(i); queue.poll(); - System.out.println("第 " + i + " 轮入队+出队后 queue = " + Arrays.toString(queue.toArray())); + System.out.println("第 " + i + " 轮入队 + 出队后 queue = " + Arrays.toString(queue.toArray())); } } } diff --git a/codes/java/chapter_stack_and_queue/array_stack.java b/codes/java/chapter_stack_and_queue/array_stack.java index 395e79e..0ac9b45 100644 --- a/codes/java/chapter_stack_and_queue/array_stack.java +++ b/codes/java/chapter_stack_and_queue/array_stack.java @@ -10,15 +10,15 @@ import java.util.*; /* 基于数组实现的栈 */ class ArrayStack { - ArrayList list; + private ArrayList stack; public ArrayStack() { // 初始化列表(动态数组) - list = new ArrayList<>(); + stack = new ArrayList<>(); } /* 获取栈的长度 */ public int size() { - return list.size(); + return stack.size(); } /* 判断栈是否为空 */ @@ -28,27 +28,27 @@ class ArrayStack { /* 入栈 */ public void push(int num) { - list.add(num); + stack.add(num); } /* 出栈 */ public int pop() { - return list.remove(size() - 1); + return stack.remove(size() - 1); } /* 访问栈顶元素 */ public int peek() { - return list.get(size() - 1); + return stack.get(size() - 1); } /* 访问索引 index 处元素 */ public int get(int index) { - return list.get(index); + return stack.get(index); } /* 将 List 转化为 Array 并返回 */ public Object[] toArray() { - return list.toArray(); + return stack.toArray(); } } @@ -79,5 +79,6 @@ public class array_stack { /* 判断是否为空 */ boolean isEmpty = stack.isEmpty(); + System.out.println("栈是否为空 = " + isEmpty); } } diff --git a/codes/java/chapter_stack_and_queue/deque.java b/codes/java/chapter_stack_and_queue/deque.java index 095e528..cdfe65b 100644 --- a/codes/java/chapter_stack_and_queue/deque.java +++ b/codes/java/chapter_stack_and_queue/deque.java @@ -10,7 +10,7 @@ import java.util.*; public class deque { public static void main(String[] args) { - /* 初始化队列 */ + /* 初始化双向队列 */ Deque deque = new LinkedList<>(); /* 元素入队 */ @@ -19,7 +19,7 @@ public class deque { deque.offerLast(4); deque.offerFirst(3); deque.offerFirst(1); - System.out.println("队列 deque = " + deque); + System.out.println("双向队列 deque = " + deque); /* 访问队首元素 */ int peekFirst = deque.peekFirst(); @@ -33,11 +33,12 @@ public class deque { int pollLast = deque.pollLast(); System.out.println("队尾出队元素 pollLast = " + pollLast + ",队尾出队后 deque = " + deque); - /* 获取队列的长度 */ + /* 获取双向队列的长度 */ int size = deque.size(); - System.out.println("队列长度 size = " + size); + System.out.println("双向队列长度 size = " + size); - /* 判断队列是否为空 */ + /* 判断双向队列是否为空 */ boolean isEmpty = deque.isEmpty(); + System.out.println("双向队列是否为空 = " + isEmpty); } } diff --git a/codes/java/chapter_stack_and_queue/linkedlist_queue.java b/codes/java/chapter_stack_and_queue/linkedlist_queue.java index 30ddeb1..9429cc3 100644 --- a/codes/java/chapter_stack_and_queue/linkedlist_queue.java +++ b/codes/java/chapter_stack_and_queue/linkedlist_queue.java @@ -77,5 +77,6 @@ public class linkedlist_queue { /* 判断队列是否为空 */ boolean isEmpty = queue.isEmpty(); + System.out.println("队列是否为空 = " + isEmpty); } } diff --git a/codes/java/chapter_stack_and_queue/linkedlist_stack.java b/codes/java/chapter_stack_and_queue/linkedlist_stack.java index 003977b..0dc4798 100644 --- a/codes/java/chapter_stack_and_queue/linkedlist_stack.java +++ b/codes/java/chapter_stack_and_queue/linkedlist_stack.java @@ -7,18 +7,20 @@ package chapter_stack_and_queue; import java.util.*; +import include.*; /* 基于链表实现的栈 */ class LinkedListStack { - LinkedList list; + private ListNode stackPeek; // 将头结点作为栈顶 + private int stackSize = 0; // 栈的长度 + public LinkedListStack() { - // 初始化链表 - list = new LinkedList<>(); + stackPeek = null; } /* 获取栈的长度 */ public int size() { - return list.size(); + return stackSize; } /* 判断栈是否为空 */ @@ -28,22 +30,38 @@ class LinkedListStack { /* 入栈 */ public void push(int num) { - list.addLast(num); + ListNode node = new ListNode(num); + node.next = stackPeek; + stackPeek = node; + stackSize++; } /* 出栈 */ public int pop() { - return list.removeLast(); + if (size() == 0) + throw new IndexOutOfBoundsException(); + int num = peek(); + stackPeek = stackPeek.next; + stackSize--; + return num; } /* 访问栈顶元素 */ public int peek() { - return list.getLast(); + if (size() == 0) + throw new IndexOutOfBoundsException(); + return stackPeek.val; } /* 将 List 转化为 Array 并返回 */ - public Object[] toArray() { - return list.toArray(); + public int[] toArray() { + ListNode node = stackPeek; + int[] res = new int[size()]; + for (int i = res.length - 1; i >= 0; i--) { + res[i] = node.val; + node = node.next; + } + return res; } } @@ -74,5 +92,6 @@ public class linkedlist_stack { /* 判断是否为空 */ boolean isEmpty = stack.isEmpty(); + System.out.println("栈是否为空 = " + isEmpty); } } diff --git a/codes/java/chapter_stack_and_queue/queue.java b/codes/java/chapter_stack_and_queue/queue.java index 4d22b50..232943f 100644 --- a/codes/java/chapter_stack_and_queue/queue.java +++ b/codes/java/chapter_stack_and_queue/queue.java @@ -35,5 +35,6 @@ public class queue { /* 判断队列是否为空 */ boolean isEmpty = queue.isEmpty(); + System.out.println("队列是否为空 = " + isEmpty); } } diff --git a/codes/java/chapter_stack_and_queue/stack.java b/codes/java/chapter_stack_and_queue/stack.java index 1ae525c..9c94eb6 100644 --- a/codes/java/chapter_stack_and_queue/stack.java +++ b/codes/java/chapter_stack_and_queue/stack.java @@ -11,22 +11,23 @@ import java.util.*; public class stack { public static void main(String[] args) { /* 初始化栈 */ - Stack stack = new Stack<>(); + // 在 Java 中,推荐将 LinkedList 当作栈来使用 + LinkedList stack = new LinkedList<>(); /* 元素入栈 */ - stack.push(1); - stack.push(3); - stack.push(2); - stack.push(5); - stack.push(4); + stack.addLast(1); + stack.addLast(3); + stack.addLast(2); + stack.addLast(5); + stack.addLast(4); System.out.println("栈 stack = " + stack); /* 访问栈顶元素 */ - int peek = stack.peek(); + int peek = stack.peekLast(); System.out.println("栈顶元素 peek = " + peek); /* 元素出栈 */ - int pop = stack.pop(); + int pop = stack.removeLast(); System.out.println("出栈元素 pop = " + pop + ",出栈后 stack = " + stack); /* 获取栈的长度 */ @@ -35,5 +36,6 @@ public class stack { /* 判断是否为空 */ boolean isEmpty = stack.isEmpty(); + System.out.println("栈是否为空 = " + isEmpty); } } diff --git a/codes/python/chapter_array_and_linkedlist/my_list.py b/codes/python/chapter_array_and_linkedlist/my_list.py index 1c178fc..5d8997b 100644 --- a/codes/python/chapter_array_and_linkedlist/my_list.py +++ b/codes/python/chapter_array_and_linkedlist/my_list.py @@ -12,64 +12,64 @@ from include import * class MyList: """ 构造函数 """ def __init__(self): - self._capacity = 10 # 列表容量 - self._nums = [0] * self._capacity # 数组(存储列表元素) - self._size = 0 # 列表长度(即当前元素数量) - self._extend_ratio = 2 # 每次列表扩容的倍数 + self.__capacity = 10 # 列表容量 + self.__nums = [0] * self.__capacity # 数组(存储列表元素) + self.__size = 0 # 列表长度(即当前元素数量) + self.__extend_ratio = 2 # 每次列表扩容的倍数 """ 获取列表长度(即当前元素数量) """ def size(self): - return self._size + return self.__size """ 获取列表容量 """ def capacity(self): - return self._capacity + return self.__capacity """ 访问元素 """ def get(self, index): # 索引如果越界则抛出异常,下同 - assert index < self._size, "索引越界" - return self._nums[index] + assert index < self.__size, "索引越界" + return self.__nums[index] """ 更新元素 """ def set(self, num, index): - assert index < self._size, "索引越界" - self._nums[index] = num + assert index < self.__size, "索引越界" + self.__nums[index] = num """ 中间插入元素 """ def add(self, num, index=-1): - assert index < self._size, "索引越界" + assert index < self.__size, "索引越界" if index == -1: - index = self._size + index = self.__size # 元素数量超出容量时,触发扩容机制 - if self._size == self.capacity(): + if self.__size == self.capacity(): self.extend_capacity() # 索引 i 以及之后的元素都向后移动一位 - for j in range(self._size - 1, index - 1, -1): - self._nums[j + 1] = self._nums[j] - self._nums[index] = num + for j in range(self.__size - 1, index - 1, -1): + self.__nums[j + 1] = self.__nums[j] + self.__nums[index] = num # 更新元素数量 - self._size += 1 + self.__size += 1 """ 删除元素 """ def remove(self, index): - assert index < self._size, "索引越界" + assert index < self.__size, "索引越界" # 索引 i 之后的元素都向前移动一位 - for j in range(index, self._size - 1): - self._nums[j] = self._nums[j + 1] + for j in range(index, self.__size - 1): + self.__nums[j] = self.__nums[j + 1] # 更新元素数量 - self._size -= 1 + self.__size -= 1 """ 列表扩容 """ def extend_capacity(self): - # 新建一个长度为 self._size 的数组,并将原数组拷贝到新数组 - self._nums = self._nums + [0] * self.capacity() * (self._extend_ratio - 1) + # 新建一个长度为 self.__size 的数组,并将原数组拷贝到新数组 + self.__nums = self.__nums + [0] * self.capacity() * (self.__extend_ratio - 1) # 更新列表容量 - self._capacity = len(self._nums) + self.__capacity = len(self.__nums) """ 返回有效长度的列表 """ def to_array(self): - return self._nums[:self._size] + return self.__nums[:self.__size] """ Driver Code """ diff --git a/codes/python/chapter_stack_and_queue/array_stack.py b/codes/python/chapter_stack_and_queue/array_stack.py index ad899d9..e0bf5f2 100644 --- a/codes/python/chapter_stack_and_queue/array_stack.py +++ b/codes/python/chapter_stack_and_queue/array_stack.py @@ -38,7 +38,7 @@ class ArrayStack: return self.__stack[index] """ 返回列表用于打印 """ - def toList(self): + def to_list(self): return self.__stack @@ -53,7 +53,7 @@ if __name__ == "__main__": stack.push(2) stack.push(5) stack.push(4) - print("栈 stack =", stack.toList()) + print("栈 stack =", stack.to_list()) """ 访问栈顶元素 """ peek = stack.peek() @@ -62,11 +62,12 @@ if __name__ == "__main__": """ 元素出栈 """ pop = stack.pop() print("出栈元素 pop =", pop) - print("出栈后 stack =", stack.toList()) + print("出栈后 stack =", stack.to_list()) """ 获取栈的长度 """ size = stack.size() print("栈的长度 size =", size) """ 判断是否为空 """ - isEmpty = stack.is_empty() + is_empty = stack.is_empty() + print("栈是否为空 =", is_empty) \ No newline at end of file diff --git a/codes/python/chapter_stack_and_queue/linkedlist_stack.py b/codes/python/chapter_stack_and_queue/linkedlist_stack.py index dce1e35..49d1366 100644 --- a/codes/python/chapter_stack_and_queue/linkedlist_stack.py +++ b/codes/python/chapter_stack_and_queue/linkedlist_stack.py @@ -11,7 +11,7 @@ from include import * """ 基于链表实现的栈 """ class LinkedListStack: def __init__(self): - self.__head = None + self.__peek = None self.__size = 0 """ 获取栈的长度 """ @@ -20,34 +20,34 @@ class LinkedListStack: """ 判断栈是否为空 """ def is_empty(self): - return not self.__head + return not self.__peek """ 入栈 """ def push(self, val): node = ListNode(val) - node.next = self.__head - self.__head = node + node.next = self.__peek + self.__peek = node self.__size += 1 """ 出栈 """ def pop(self): # 判空处理 - if not self.__head: return None - pop = self.__head.val - self.__head = self.__head.next + if not self.__peek: return None + pop = self.__peek.val + self.__peek = self.__peek.next self.__size -= 1 return pop """ 访问栈顶元素 """ def peek(self): # 判空处理 - if not self.__head: return None - return self.__head.val + if not self.__peek: return None + return self.__peek.val """ 转化为列表用于打印 """ def to_list(self): arr = [] - node = self.__head + node = self.__peek while node: arr.append(node.val) node = node.next @@ -82,4 +82,5 @@ if __name__ == "__main__": print("栈的长度 size =", size) """ 判断是否为空 """ - isEmpty = stack.is_empty() + is_empty = stack.is_empty() + print("栈是否为空 =", is_empty) diff --git a/codes/python/chapter_stack_and_queue/stack.py b/codes/python/chapter_stack_and_queue/stack.py index 80e7fcc..a8d2a7a 100644 --- a/codes/python/chapter_stack_and_queue/stack.py +++ b/codes/python/chapter_stack_and_queue/stack.py @@ -37,4 +37,5 @@ if __name__ == "__main__": print("栈的长度 size =", size) """ 判断是否为空 """ - isEmpty = len(stack) == 0 + is_empty = len(stack) == 0 + print("栈是否为空 =", is_empty) diff --git a/docs/chapter_array_and_linkedlist/list.md b/docs/chapter_array_and_linkedlist/list.md index a8310ec..11dd816 100644 --- a/docs/chapter_array_and_linkedlist/list.md +++ b/docs/chapter_array_and_linkedlist/list.md @@ -356,14 +356,14 @@ comments: true int get(int index) { // 索引如果越界则抛出异常,下同 if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); return nums[index]; } /* 更新元素 */ void set(int index, int num) { if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); nums[index] = num; } @@ -380,7 +380,7 @@ comments: true /* 中间插入元素 */ void insert(int index, int num) { if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); // 元素数量超出容量时,触发扩容机制 if (size() == capacity()) extendCapacity(); @@ -396,7 +396,7 @@ comments: true /* 删除元素 */ void remove(int index) { if (index >= size()) - throw std::out_of_range ("索引越界"); + throw out_of_range("索引越界"); // 索引 i 之后的元素都向前移动一位 for (int j = index; j < size() - 1; j++) { nums[j] = nums[j + 1]; @@ -439,58 +439,58 @@ comments: true class MyList: """ 构造函数 """ def __init__(self): - self._capacity = 10 # 列表容量 - self._nums = [0] * self._capacity # 数组(存储列表元素) - self._size = 0 # 列表长度(即当前元素数量) - self._extend_ratio = 2 # 每次列表扩容的倍数 + self.__capacity = 10 # 列表容量 + self.__nums = [0] * self.__capacity # 数组(存储列表元素) + self.__size = 0 # 列表长度(即当前元素数量) + self.__extend_ratio = 2 # 每次列表扩容的倍数 """ 获取列表长度(即当前元素数量) """ def size(self): - return self._size + return self.__size """ 获取列表容量 """ def capacity(self): - return self._capacity + return self.__capacity """ 访问元素 """ def get(self, index): # 索引如果越界则抛出异常,下同 - assert index < self._size, "索引越界" - return self._nums[index] + assert index < self.__size, "索引越界" + return self.__nums[index] """ 更新元素 """ def set(self, num, index): - assert index < self._size, "索引越界" - self._nums[index] = num + assert index < self.__size, "索引越界" + self.__nums[index] = num """ 中间插入元素 """ def add(self, num, index=-1): - assert index < self._size, "索引越界" + assert index < self.__size, "索引越界" if index == -1: - index = self._size + index = self.__size # 元素数量超出容量时,触发扩容机制 - if self._size == self.capacity(): + if self.__size == self.capacity(): self.extend_capacity() # 索引 i 以及之后的元素都向后移动一位 - for j in range(self._size - 1, index - 1, -1): - self._nums[j + 1] = self._nums[j] - self._nums[index] = num + for j in range(self.__size - 1, index - 1, -1): + self.__nums[j + 1] = self.__nums[j] + self.__nums[index] = num # 更新元素数量 - self._size += 1 + self.__size += 1 """ 删除元素 """ def remove(self, index): - assert index < self._size, "索引越界" + assert index < self.__size, "索引越界" # 索引 i 之后的元素都向前移动一位 - for j in range(index, self._size - 1): - self._nums[j] = self._nums[j + 1] + for j in range(index, self.__size - 1): + self.__nums[j] = self.__nums[j + 1] # 更新元素数量 - self._size -= 1 + self.__size -= 1 """ 列表扩容 """ def extend_capacity(self): - # 新建一个长度为 self._size 的数组,并将原数组拷贝到新数组 - self._nums = self._nums + [0] * self.capacity() * (self._extend_ratio - 1) + # 新建一个长度为 self.__size 的数组,并将原数组拷贝到新数组 + self.__nums = self.__nums + [0] * self.capacity() * (self.__extend_ratio - 1) # 更新列表容量 - self._capacity = len(self._nums) + self.__capacity = len(self.__nums) ``` diff --git a/docs/chapter_stack_and_queue/deque.md b/docs/chapter_stack_and_queue/deque.md index eef13e7..407d353 100644 --- a/docs/chapter_stack_and_queue/deque.md +++ b/docs/chapter_stack_and_queue/deque.md @@ -38,35 +38,34 @@ comments: true ```java title="deque.java" /* 初始化双向队列 */ Deque deque = new LinkedList<>(); - + /* 元素入队 */ deque.offerLast(2); deque.offerLast(5); deque.offerLast(4); deque.offerFirst(3); deque.offerFirst(1); - System.out.println("队列 deque = " + deque); - + System.out.println("双向队列 deque = " + deque); + /* 访问队首元素 */ int peekFirst = deque.peekFirst(); System.out.println("队首元素 peekFirst = " + peekFirst); int peekLast = deque.peekLast(); System.out.println("队尾元素 peekLast = " + peekLast); - + /* 元素出队 */ int pollFirst = deque.pollFirst(); - System.out.println("队首出队元素 pollFirst = " + pollFirst + - ",队首出队后 deque = " + deque); + System.out.println("队首出队元素 pollFirst = " + pollFirst + ",队首出队后 deque = " + deque); int pollLast = deque.pollLast(); - System.out.println("队尾出队元素 pollLast = " + pollLast + - ",队尾出队后 deque = " + deque); - - /* 获取队列的长度 */ + System.out.println("队尾出队元素 pollLast = " + pollLast + ",队尾出队后 deque = " + deque); + + /* 获取双向队列的长度 */ int size = deque.size(); - System.out.println("队列长度 size = " + size); - - /* 判断队列是否为空 */ + System.out.println("双向队列长度 size = " + size); + + /* 判断双向队列是否为空 */ boolean isEmpty = deque.isEmpty(); + System.out.println("双向队列是否为空 = " + isEmpty); ``` === "C++" diff --git a/docs/chapter_stack_and_queue/queue.md b/docs/chapter_stack_and_queue/queue.md index 0788ef0..0637688 100644 --- a/docs/chapter_stack_and_queue/queue.md +++ b/docs/chapter_stack_and_queue/queue.md @@ -60,6 +60,7 @@ comments: true /* 判断队列是否为空 */ boolean isEmpty = queue.isEmpty(); + System.out.println("队列是否为空 = " + isEmpty); ``` === "C++" @@ -145,10 +146,9 @@ comments: true ```java title="array_queue.java" /* 基于环形数组实现的队列 */ class ArrayQueue { - int[] nums; // 用于存储队列元素的数组 - int size = 0; // 队列长度(即元素个数) - int front = 0; // 头指针,指向队首 - int rear = 0; // 尾指针,指向队尾 + 1 + private int[] nums; // 用于存储队列元素的数组 + private int front = 0; // 头指针,指向队首 + private int rear = 0; // 尾指针,指向队尾 + 1 public ArrayQueue(int capacity) { // 初始化数组 diff --git a/docs/chapter_stack_and_queue/stack.md b/docs/chapter_stack_and_queue/stack.md index aa0b312..b7b3e93 100644 --- a/docs/chapter_stack_and_queue/stack.md +++ b/docs/chapter_stack_and_queue/stack.md @@ -36,22 +36,23 @@ comments: true ```java title="stack.java" /* 初始化栈 */ - Stack stack = new Stack<>(); + // 在 Java 中,推荐将 LinkedList 当作栈来使用 + LinkedList stack = new LinkedList<>(); /* 元素入栈 */ - stack.push(1); - stack.push(3); - stack.push(2); - stack.push(5); - stack.push(4); + stack.addLast(1); + stack.addLast(3); + stack.addLast(2); + stack.addLast(5); + stack.addLast(4); System.out.println("栈 stack = " + stack); /* 访问栈顶元素 */ - int peek = stack.peek(); + int peek = stack.peekLast(); System.out.println("栈顶元素 peek = " + peek); /* 元素出栈 */ - int pop = stack.pop(); + int pop = stack.removeLast(); System.out.println("出栈元素 pop = " + pop + ",出栈后 stack = " + stack); /* 获取栈的长度 */ @@ -60,18 +61,73 @@ comments: true /* 判断是否为空 */ boolean isEmpty = stack.isEmpty(); + System.out.println("栈是否为空 = " + isEmpty); ``` === "C++" ```cpp title="stack.cpp" - + /* 初始化栈 */ + stack stack; + + /* 元素入栈 */ + stack.push(1); + stack.push(3); + stack.push(2); + stack.push(5); + stack.push(4); + cout << "栈 stack = "; + PrintUtil::printStack(stack); + + /* 访问栈顶元素 */ + int top = stack.top(); + cout << "栈顶元素 top = " << top << endl; + + /* 元素出栈 */ + stack.pop(); + cout << "出栈元素 pop = " << top << ",出栈后 stack = "; + PrintUtil::printStack(stack); + + /* 获取栈的长度 */ + int size = stack.size(); + cout << "栈的长度 size = " << size << endl; + + /* 判断是否为空 */ + bool empty = stack.empty(); + cout << "栈是否为空 = " << empty << endl; ``` === "Python" ```python title="stack.py" - + """ 初始化栈 """ + # Python 没有内置的栈类,可以把 list 当作栈来使用 + stack = [] + + """ 元素入栈 """ + stack.append(1) + stack.append(3) + stack.append(2) + stack.append(5) + stack.append(4) + print("栈 stack =", stack) + + """ 访问栈顶元素 """ + peek = stack[-1] + print("栈顶元素 peek =", peek) + + """ 元素出栈 """ + pop = stack.pop() + print("出栈元素 pop =", pop) + print("出栈后 stack =", stack) + + """ 获取栈的长度 """ + size = len(stack) + print("栈的长度 size =", size) + + """ 判断是否为空 """ + is_empty = len(stack) == 0 + print("栈是否为空 =", is_empty) ``` ## 栈的实现 @@ -91,14 +147,15 @@ comments: true ```java title="linkedlist_stack.java" /* 基于链表实现的栈 */ class LinkedListStack { - LinkedList list; + private ListNode stackPeek; // 将头结点作为栈顶 + private int stackSize = 0; // 栈的长度 + public LinkedListStack() { - // 初始化链表 - list = new LinkedList<>(); + stackPeek = null; } /* 获取栈的长度 */ public int size() { - return list.size(); + return stackSize; } /* 判断栈是否为空 */ public boolean isEmpty() { @@ -106,15 +163,25 @@ comments: true } /* 入栈 */ public void push(int num) { - list.addLast(num); + ListNode node = new ListNode(num); + node.next = stackPeek; + stackPeek = node; + stackSize++; } /* 出栈 */ public int pop() { - return list.removeLast(); + if (size() == 0) + throw new IndexOutOfBoundsException(); + int num = peek(); + stackPeek = stackPeek.next; + stackSize--; + return num; } /* 访问栈顶元素 */ public int peek() { - return list.getLast(); + if (size() == 0) + throw new IndexOutOfBoundsException(); + return stackPeek.val; } } ``` @@ -122,13 +189,88 @@ comments: true === "C++" ```cpp title="linkedlist_stack.cpp" - + /* 基于链表实现的栈 */ + class LinkedListStack { + private: + ListNode* stackTop; // 将头结点作为栈顶 + int stackSize; // 栈的长度 + + public: + LinkedListStack() { + stackTop = nullptr; + stackSize = 0; + } + /* 获取栈的长度 */ + int size() { + return stackSize; + } + /* 判断栈是否为空 */ + bool empty() { + return size() == 0; + } + /* 入栈 */ + void push(int num) { + ListNode* node = new ListNode(num); + node->next = stackTop; + stackTop = node; + stackSize++; + } + /* 出栈 */ + int pop() { + if (size() == 0) + throw out_of_range("栈为空"); + int num = stackTop->val; + stackTop = stackTop->next; + stackSize--; + return num; + } + /* 访问栈顶元素 */ + int top() { + if (size() == 0) + throw out_of_range("栈为空"); + return stackTop->val; + } + }; ``` === "Python" ```python title="linkedlist_stack.py" - + """ 基于链表实现的栈 """ + class LinkedListStack: + def __init__(self): + self.__peek = None + self.__size = 0 + + """ 获取栈的长度 """ + def size(self): + return self.__size + + """ 判断栈是否为空 """ + def is_empty(self): + return not self.__peek + + """ 入栈 """ + def push(self, val): + node = ListNode(val) + node.next = self.__peek + self.__peek = node + self.__size += 1 + + """ 出栈 """ + def pop(self): + # 判空处理 + if not self.__peek: return None + pop = self.__peek.val + self.__peek = self.__peek.next + self.__size -= 1 + return pop + + """ 访问栈顶元素 """ + def peek(self): + # 判空处理 + if not self.__peek: return None + return self.__peek.val ``` ### 基于数组的实现 @@ -142,14 +284,14 @@ comments: true ```java title="array_stack.java" /* 基于数组实现的栈 */ class ArrayStack { - List list; + private ArrayList stack; public ArrayStack() { // 初始化列表(动态数组) - list = new ArrayList<>(); + stack = new ArrayList<>(); } /* 获取栈的长度 */ public int size() { - return list.size(); + return stack.size(); } /* 判断栈是否为空 */ public boolean isEmpty() { @@ -157,19 +299,19 @@ comments: true } /* 入栈 */ public void push(int num) { - list.add(num); + stack.add(num); } /* 出栈 */ public int pop() { - return list.remove(size() - 1); + return stack.remove(size() - 1); } /* 访问栈顶元素 */ public int peek() { - return list.get(size() - 1); + return stack.get(size() - 1); } /* 访问索引 index 处元素 */ public int get(int index) { - return list.get(index); + return stack.get(index); } } ``` @@ -177,13 +319,72 @@ comments: true === "C++" ```cpp title="array_stack.cpp" - + /* 基于数组实现的栈 */ + class ArrayStack { + private: + vector stack; + + public: + /* 获取栈的长度 */ + int size() { + return stack.size(); + } + /* 判断栈是否为空 */ + bool empty() { + return stack.empty(); + } + /* 入栈 */ + void push(int num) { + stack.push_back(num); + } + /* 出栈 */ + int pop() { + int oldTop = stack.back(); + stack.pop_back(); + return oldTop; + } + /* 访问栈顶元素 */ + int top() { + return stack.back(); + } + /* 访问索引 index 处元素 */ + int get(int index) { + return stack[index]; + } + }; ``` === "Python" ```python title="array_stack.py" - + """ 基于数组实现的栈 """ + class ArrayStack: + def __init__(self): + self.__stack = [] + + """ 获取栈的长度 """ + def size(self): + return len(self.__stack) + + """ 判断栈是否为空 """ + def is_empty(self): + return self.__stack == [] + + """ 入栈 """ + def push(self, item): + self.__stack.append(item) + + """ 出栈 """ + def pop(self): + return self.__stack.pop() + + """ 访问栈顶元素 """ + def peek(self): + return self.__stack[-1] + + """ 访问索引 index 处元素 """ + def get(self, index): + return self.__stack[index] ``` !!! tip @@ -193,5 +394,4 @@ comments: true ## 栈典型应用 - **浏览器中的后退与前进、软件中的撤销与反撤销。** 每当我们打开新的网页,浏览器就讲上一个网页执行入栈,这样我们就可以通过「后退」操作来回到上一页面,后退操作实际上是在执行出栈。如果要同时支持后退和前进,那么则需要两个栈来配合实现。 - - **程序内存管理。** 每当调用函数时,系统就会在栈顶添加一个栈帧,用来记录函数的上下文信息。在递归函数中,向下递推会不断执行入栈,向上回溯阶段时出栈。