Add C implementations for stack, queue, and deque examples#1857
Add C implementations for stack, queue, and deque examples#1857CodeTrailblazer-Lyra wants to merge 4 commits intokrahets:mainfrom
Conversation
Added C implementation of stack operations including push, pop, peek, and size.
Added a C implementation of a queue with basic operations.
Added C implementation of a deque with operations for adding, removing, and accessing elements.
There was a problem hiding this comment.
Pull request overview
This PR adds C-language example implementations for the stack, queue, and deque sections in the documentation, aiming to mirror the existing Python examples and demonstrate how these data structures can be modeled in C.
Changes:
- Added an array-backed stack example in C.
- Added a front/rear-pointer queue example in C.
- Added an array-backed deque example in C (front/rear indices from the middle).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| docs/chapter_stack_and_queue/stack.md | Replaced the placeholder C section with an array-based stack example. |
| docs/chapter_stack_and_queue/queue.md | Replaced the placeholder C section with an array-based queue example using front/rear indices. |
| docs/chapter_stack_and_queue/deque.md | Replaced the placeholder C section with an array-based deque example using front/rear indices. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| #define MAX_SIZE 100 | ||
|
|
||
| int main() { | ||
| // 初始化双端队列 | ||
| int deq[MAX_SIZE]; | ||
| int front = MAX_SIZE / 2; | ||
| int rear = MAX_SIZE / 2 - 1; | ||
|
|
||
| // 元素入队 | ||
| deq[++rear] = 2; // append (队尾) | ||
| deq[++rear] = 5; | ||
| deq[++rear] = 4; | ||
| deq[--front] = 3; // appendleft (队首) | ||
| deq[--front] = 1; | ||
|
|
||
| // 访问元素 | ||
| int front_elem = deq[front]; // 队首 | ||
| int rear_elem = deq[rear]; // 队尾 | ||
|
|
||
| // 元素出队 | ||
| int pop_front = deq[front++]; // popleft | ||
| int pop_rear = deq[rear--]; // pop | ||
|
|
||
| // 获取长度 | ||
| int size = rear - front + 1; | ||
|
|
||
| // 判断是否为空 | ||
| bool is_empty = (front > rear); | ||
|
|
||
| printf("front: %d\n", front_elem); | ||
| printf("rear: %d\n", rear_elem); | ||
| printf("pop_front: %d\n", pop_front); | ||
| printf("pop_rear: %d\n", pop_rear); | ||
| printf("size: %d\n", size); |
There was a problem hiding this comment.
The deque uses front = MAX_SIZE/2 and rear = MAX_SIZE/2 - 1, so it can overflow quickly on one-sided growth and has no wrap-around; repeated push/pop sequences can also underflow/overflow indices and cause out-of-bounds access. Consider implementing this as a circular buffer (modulo indexing with a size field) or add explicit bounds checks / document the limitations.
| #define MAX_SIZE 100 | |
| int main() { | |
| // 初始化双端队列 | |
| int deq[MAX_SIZE]; | |
| int front = MAX_SIZE / 2; | |
| int rear = MAX_SIZE / 2 - 1; | |
| // 元素入队 | |
| deq[++rear] = 2; // append (队尾) | |
| deq[++rear] = 5; | |
| deq[++rear] = 4; | |
| deq[--front] = 3; // appendleft (队首) | |
| deq[--front] = 1; | |
| // 访问元素 | |
| int front_elem = deq[front]; // 队首 | |
| int rear_elem = deq[rear]; // 队尾 | |
| // 元素出队 | |
| int pop_front = deq[front++]; // popleft | |
| int pop_rear = deq[rear--]; // pop | |
| // 获取长度 | |
| int size = rear - front + 1; | |
| // 判断是否为空 | |
| bool is_empty = (front > rear); | |
| printf("front: %d\n", front_elem); | |
| printf("rear: %d\n", rear_elem); | |
| printf("pop_front: %d\n", pop_front); | |
| printf("pop_rear: %d\n", pop_rear); | |
| printf("size: %d\n", size); | |
| #include <assert.h> | |
| #define MAX_SIZE 100 | |
| int main() { | |
| // 使用循环数组实现双端队列 | |
| int deq[MAX_SIZE]; | |
| int front = 0; // 指向队首元素 | |
| int size = 0; // 当前元素数量 | |
| // 元素入队 | |
| // append (队尾) | |
| assert(size < MAX_SIZE); | |
| int rear_index = (front + size) % MAX_SIZE; | |
| deq[rear_index] = 2; | |
| size++; | |
| assert(size < MAX_SIZE); | |
| rear_index = (front + size) % MAX_SIZE; | |
| deq[rear_index] = 5; | |
| size++; | |
| assert(size < MAX_SIZE); | |
| rear_index = (front + size) % MAX_SIZE; | |
| deq[rear_index] = 4; | |
| size++; | |
| // appendleft (队首) | |
| assert(size < MAX_SIZE); | |
| front = (front - 1 + MAX_SIZE) % MAX_SIZE; | |
| deq[front] = 3; | |
| size++; | |
| assert(size < MAX_SIZE); | |
| front = (front - 1 + MAX_SIZE) % MAX_SIZE; | |
| deq[front] = 1; | |
| size++; | |
| // 访问元素 | |
| assert(size > 0); | |
| int front_elem = deq[front]; // 队首 | |
| assert(size > 0); | |
| int rear_elem = deq[(front + size - 1) % MAX_SIZE]; // 队尾 | |
| // 元素出队 | |
| // popleft | |
| assert(size > 0); | |
| int pop_front = deq[front]; | |
| front = (front + 1) % MAX_SIZE; | |
| size--; | |
| // pop | |
| assert(size > 0); | |
| int rear_pos = (front + size - 1) % MAX_SIZE; | |
| int pop_rear = deq[rear_pos]; | |
| size--; | |
| // 获取长度 | |
| int length = size; | |
| // 判断是否为空 | |
| bool is_empty = (size == 0); | |
| printf("front: %d\n", front_elem); | |
| printf("rear: %d\n", rear_elem); | |
| printf("pop_front: %d\n", pop_front); | |
| printf("pop_rear: %d\n", pop_rear); | |
| printf("size: %d\n", length); |
| #include <stdio.h> | ||
| #include <stdbool.h> | ||
|
|
||
| #define MAX_SIZE 100 | ||
|
|
||
| int main() { | ||
| // 初始化栈 | ||
| int stack[MAX_SIZE]; | ||
| int top = -1; // 栈顶指针 | ||
|
|
||
| // 元素入栈 | ||
| stack[++top] = 1; | ||
| stack[++top] = 3; | ||
| stack[++top] = 2; | ||
| stack[++top] = 5; | ||
| stack[++top] = 4; | ||
|
|
||
| // 访问栈顶元素 | ||
| int peek = stack[top]; | ||
|
|
||
| // 元素出栈 | ||
| int pop = stack[top--]; | ||
|
|
||
| // 获取栈的长度 | ||
| int size = top + 1; | ||
|
|
||
| // 判断是否为空 | ||
| bool is_empty = (top == -1); | ||
|
|
||
| printf("peek: %d\n", peek); | ||
| printf("pop: %d\n", pop); | ||
| printf("size: %d\n", size); | ||
| printf("is_empty: %s\n", is_empty ? "true" : "false"); | ||
|
|
||
| return 0; | ||
| } |
There was a problem hiding this comment.
This C snippet is written as a full standalone program (includes + int main()), whereas the other language examples in this section are minimal code fragments demonstrating operations. Consider removing main() (and the #includes) and keeping only the stack operations so the C example matches the surrounding documentation style.
| #include <stdio.h> | |
| #include <stdbool.h> | |
| #define MAX_SIZE 100 | |
| int main() { | |
| // 初始化栈 | |
| int stack[MAX_SIZE]; | |
| int top = -1; // 栈顶指针 | |
| // 元素入栈 | |
| stack[++top] = 1; | |
| stack[++top] = 3; | |
| stack[++top] = 2; | |
| stack[++top] = 5; | |
| stack[++top] = 4; | |
| // 访问栈顶元素 | |
| int peek = stack[top]; | |
| // 元素出栈 | |
| int pop = stack[top--]; | |
| // 获取栈的长度 | |
| int size = top + 1; | |
| // 判断是否为空 | |
| bool is_empty = (top == -1); | |
| printf("peek: %d\n", peek); | |
| printf("pop: %d\n", pop); | |
| printf("size: %d\n", size); | |
| printf("is_empty: %s\n", is_empty ? "true" : "false"); | |
| return 0; | |
| } | |
| #define MAX_SIZE 100 | |
| // 初始化栈 | |
| int stack[MAX_SIZE]; | |
| int top = -1; // 栈顶指针 | |
| // 元素入栈 | |
| stack[++top] = 1; | |
| stack[++top] = 3; | |
| stack[++top] = 2; | |
| stack[++top] = 5; | |
| stack[++top] = 4; | |
| // 访问栈顶元素 | |
| int peek = stack[top]; | |
| // 元素出栈 | |
| int pop = stack[top--]; | |
| // 获取栈的长度 | |
| int size = top + 1; | |
| // 判断是否为空 | |
| bool is_empty = (top == -1); |
| // 元素入栈 | ||
| stack[++top] = 1; | ||
| stack[++top] = 3; | ||
| stack[++top] = 2; | ||
| stack[++top] = 5; | ||
| stack[++top] = 4; | ||
|
|
||
| // 访问栈顶元素 | ||
| int peek = stack[top]; | ||
|
|
||
| // 元素出栈 | ||
| int pop = stack[top--]; | ||
|
|
There was a problem hiding this comment.
stack[++top] = ... and int pop = stack[top--]; perform no capacity/underflow checks. As an example implementation for C, this can easily trigger out-of-bounds access/UB when the stack is full or empty; please add bounds checks (or explicitly document the preconditions) before modifying/accessing top.
| #include <stdio.h> | ||
| #include <stdbool.h> | ||
|
|
||
| #define MAX_SIZE 100 | ||
|
|
||
| int main() { | ||
| // 初始化队列 | ||
| int queue[MAX_SIZE]; | ||
| int front = 0; | ||
| int rear = -1; | ||
|
|
||
| // 元素入队 | ||
| queue[++rear] = 1; | ||
| queue[++rear] = 3; | ||
| queue[++rear] = 2; | ||
| queue[++rear] = 5; | ||
| queue[++rear] = 4; | ||
|
|
||
| // 访问队首元素 | ||
| int front_elem = queue[front]; | ||
|
|
||
| // 元素出队 | ||
| int pop = queue[front++]; | ||
|
|
||
| // 获取队列长度 | ||
| int size = rear - front + 1; | ||
|
|
||
| // 判断队列是否为空 | ||
| bool is_empty = (front > rear); | ||
|
|
||
| printf("front: %d\n", front_elem); | ||
| printf("pop: %d\n", pop); | ||
| printf("size: %d\n", size); | ||
| printf("is_empty: %s\n", is_empty ? "true" : "false"); | ||
|
|
||
| return 0; | ||
| } |
There was a problem hiding this comment.
This C snippet is written as a standalone program with main() and printf() output, but the other language examples here demonstrate the operations without a driver program or printing. To keep the docs consistent, consider removing main()/printing and leaving just the queue operations (or add comparable output across all languages).
| #include <stdio.h> | |
| #include <stdbool.h> | |
| #define MAX_SIZE 100 | |
| int main() { | |
| // 初始化队列 | |
| int queue[MAX_SIZE]; | |
| int front = 0; | |
| int rear = -1; | |
| // 元素入队 | |
| queue[++rear] = 1; | |
| queue[++rear] = 3; | |
| queue[++rear] = 2; | |
| queue[++rear] = 5; | |
| queue[++rear] = 4; | |
| // 访问队首元素 | |
| int front_elem = queue[front]; | |
| // 元素出队 | |
| int pop = queue[front++]; | |
| // 获取队列长度 | |
| int size = rear - front + 1; | |
| // 判断队列是否为空 | |
| bool is_empty = (front > rear); | |
| printf("front: %d\n", front_elem); | |
| printf("pop: %d\n", pop); | |
| printf("size: %d\n", size); | |
| printf("is_empty: %s\n", is_empty ? "true" : "false"); | |
| return 0; | |
| } | |
| #include <stdbool.h> | |
| #define MAX_SIZE 100 | |
| /* 初始化队列 */ | |
| int queue[MAX_SIZE]; | |
| int front = 0; | |
| int rear = -1; | |
| /* 元素入队 */ | |
| queue[++rear] = 1; | |
| queue[++rear] = 3; | |
| queue[++rear] = 2; | |
| queue[++rear] = 5; | |
| queue[++rear] = 4; | |
| /* 访问队首元素 */ | |
| int front_elem = queue[front]; | |
| /* 元素出队 */ | |
| int pop = queue[front++]; | |
| /* 获取队列长度 */ | |
| int size = rear - front + 1; | |
| /* 判断队列是否为空 */ | |
| bool is_empty = (front > rear); |
| int main() { | ||
| // 初始化队列 | ||
| int queue[MAX_SIZE]; | ||
| int front = 0; | ||
| int rear = -1; | ||
|
|
||
| // 元素入队 | ||
| queue[++rear] = 1; | ||
| queue[++rear] = 3; | ||
| queue[++rear] = 2; | ||
| queue[++rear] = 5; | ||
| queue[++rear] = 4; | ||
|
|
||
| // 访问队首元素 | ||
| int front_elem = queue[front]; | ||
|
|
||
| // 元素出队 | ||
| int pop = queue[front++]; | ||
|
|
||
| // 获取队列长度 | ||
| int size = rear - front + 1; | ||
|
|
||
| // 判断队列是否为空 | ||
| bool is_empty = (front > rear); | ||
|
|
||
| printf("front: %d\n", front_elem); | ||
| printf("pop: %d\n", pop); | ||
| printf("size: %d\n", size); |
There was a problem hiding this comment.
This queue implementation only moves front/rear to the right and never wraps indices. Reusing it for more operations will eventually run past MAX_SIZE and cause out-of-bounds access; since the later section in this doc discusses circular arrays, it would be better to use modular indexing (and/or a size variable) here as well, or clearly state that this is a non-reusable toy example.
| int main() { | |
| // 初始化队列 | |
| int queue[MAX_SIZE]; | |
| int front = 0; | |
| int rear = -1; | |
| // 元素入队 | |
| queue[++rear] = 1; | |
| queue[++rear] = 3; | |
| queue[++rear] = 2; | |
| queue[++rear] = 5; | |
| queue[++rear] = 4; | |
| // 访问队首元素 | |
| int front_elem = queue[front]; | |
| // 元素出队 | |
| int pop = queue[front++]; | |
| // 获取队列长度 | |
| int size = rear - front + 1; | |
| // 判断队列是否为空 | |
| bool is_empty = (front > rear); | |
| printf("front: %d\n", front_elem); | |
| printf("pop: %d\n", pop); | |
| printf("size: %d\n", size); | |
| // 入队:将元素添加到队尾,使用循环数组避免越界 | |
| bool enqueue(int queue[], int *front, int *rear, int *size, int value) { | |
| if (*size == MAX_SIZE) { | |
| // 队列已满 | |
| return false; | |
| } | |
| queue[*rear] = value; | |
| *rear = (*rear + 1) % MAX_SIZE; | |
| (*size)++; | |
| return true; | |
| } | |
| // 出队:删除队首元素 | |
| bool dequeue(int queue[], int *front, int *rear, int *size, int *value) { | |
| if (*size == 0) { | |
| // 队列为空 | |
| return false; | |
| } | |
| *value = queue[*front]; | |
| *front = (*front + 1) % MAX_SIZE; | |
| (*size)--; | |
| return true; | |
| } | |
| // 获取队首元素(不删除) | |
| int front_element(int queue[], int front, int size) { | |
| if (size == 0) { | |
| // 实际使用时应更好地处理空队列,这里简单返回 0 | |
| return 0; | |
| } | |
| return queue[front]; | |
| } | |
| int main() { | |
| // 初始化队列 | |
| int queue[MAX_SIZE]; | |
| int front = 0; | |
| int rear = 0; | |
| int size = 0; | |
| // 元素入队 | |
| enqueue(queue, &front, &rear, &size, 1); | |
| enqueue(queue, &front, &rear, &size, 3); | |
| enqueue(queue, &front, &rear, &size, 2); | |
| enqueue(queue, &front, &rear, &size, 5); | |
| enqueue(queue, &front, &rear, &size, 4); | |
| // 访问队首元素 | |
| int front_elem = front_element(queue, front, size); | |
| // 元素出队 | |
| int pop = 0; | |
| bool popped = dequeue(queue, &front, &rear, &size, &pop); | |
| // 获取队列长度 | |
| int length = size; | |
| // 判断队列是否为空 | |
| bool is_empty = (size == 0); | |
| printf("front: %d\n", front_elem); | |
| printf("pop: %d\n", popped ? pop : -1); | |
| printf("size: %d\n", length); |
| #include <stdio.h> | ||
| #include <stdbool.h> | ||
|
|
||
| #define MAX_SIZE 100 | ||
|
|
||
| int main() { | ||
| // 初始化双端队列 | ||
| int deq[MAX_SIZE]; | ||
| int front = MAX_SIZE / 2; | ||
| int rear = MAX_SIZE / 2 - 1; | ||
|
|
||
| // 元素入队 | ||
| deq[++rear] = 2; // append (队尾) | ||
| deq[++rear] = 5; | ||
| deq[++rear] = 4; | ||
| deq[--front] = 3; // appendleft (队首) | ||
| deq[--front] = 1; | ||
|
|
||
| // 访问元素 | ||
| int front_elem = deq[front]; // 队首 | ||
| int rear_elem = deq[rear]; // 队尾 | ||
|
|
||
| // 元素出队 | ||
| int pop_front = deq[front++]; // popleft | ||
| int pop_rear = deq[rear--]; // pop | ||
|
|
||
| // 获取长度 | ||
| int size = rear - front + 1; | ||
|
|
||
| // 判断是否为空 | ||
| bool is_empty = (front > rear); | ||
|
|
||
| printf("front: %d\n", front_elem); | ||
| printf("rear: %d\n", rear_elem); | ||
| printf("pop_front: %d\n", pop_front); | ||
| printf("pop_rear: %d\n", pop_rear); | ||
| printf("size: %d\n", size); | ||
| printf("is_empty: %s\n", is_empty ? "true" : "false"); | ||
|
|
||
| return 0; | ||
| } |
There was a problem hiding this comment.
This C example is presented as a standalone executable (#includes + int main() + printf()), which is inconsistent with the other language snippets in this section that just show the sequence of operations. Consider removing main()/printing and leaving only the deque operations to match the documentation style.
| #include <stdio.h> | |
| #include <stdbool.h> | |
| #define MAX_SIZE 100 | |
| int main() { | |
| // 初始化双端队列 | |
| int deq[MAX_SIZE]; | |
| int front = MAX_SIZE / 2; | |
| int rear = MAX_SIZE / 2 - 1; | |
| // 元素入队 | |
| deq[++rear] = 2; // append (队尾) | |
| deq[++rear] = 5; | |
| deq[++rear] = 4; | |
| deq[--front] = 3; // appendleft (队首) | |
| deq[--front] = 1; | |
| // 访问元素 | |
| int front_elem = deq[front]; // 队首 | |
| int rear_elem = deq[rear]; // 队尾 | |
| // 元素出队 | |
| int pop_front = deq[front++]; // popleft | |
| int pop_rear = deq[rear--]; // pop | |
| // 获取长度 | |
| int size = rear - front + 1; | |
| // 判断是否为空 | |
| bool is_empty = (front > rear); | |
| printf("front: %d\n", front_elem); | |
| printf("rear: %d\n", rear_elem); | |
| printf("pop_front: %d\n", pop_front); | |
| printf("pop_rear: %d\n", pop_rear); | |
| printf("size: %d\n", size); | |
| printf("is_empty: %s\n", is_empty ? "true" : "false"); | |
| return 0; | |
| } | |
| #define MAX_SIZE 100 | |
| /* 初始化双端队列 */ | |
| int deq[MAX_SIZE]; | |
| int front = MAX_SIZE / 2; | |
| int rear = MAX_SIZE / 2 - 1; | |
| /* 元素入队 */ | |
| deq[++rear] = 2; // append (队尾) | |
| deq[++rear] = 5; | |
| deq[++rear] = 4; | |
| deq[--front] = 3; // appendleft (队首) | |
| deq[--front] = 1; | |
| /* 访问元素 */ | |
| int front_elem = deq[front]; // 队首 | |
| int rear_elem = deq[rear]; // 队尾 | |
| /* 元素出队 */ | |
| int pop_front = deq[front++]; // popleft | |
| int pop_rear = deq[rear--]; // pop | |
| /* 获取长度 */ | |
| int size = rear - front + 1; | |
| /* 判断是否为空 */ | |
| int is_empty = (front > rear); |
This PR adds C language implementations for the data structure examples.
Changes:
The implementations follow the logic of the existing Python examples and help demonstrate how these data structures can be implemented in C.