【秋招】嵌入式面试八股文 - 数据结构 队列与栈篇
【秋招】嵌入式面试八股文 - 最全专栏
一、栈(Stack)基础
1. 基本概念
- 栈是一种遵循后进先出(LIFO, Last In First Out)原则的线性数据结构
- 只允许在一端(栈顶)进行插入和删除操作
- 基本操作:push(入栈)、pop(出栈)、peek/top(查看栈顶元素)
2. 栈的实现方式
数组实现
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int top; // 栈顶指针
} ArrayStack;
// 初始化栈
void initStack(ArrayStack* stack) {
stack->top = -1; // 栈空时top为-1
}
// 判断栈是否为空
bool isEmpty(ArrayStack* stack) {
return stack->top == -1;
}
// 判断栈是否已满
bool isFull(ArrayStack* stack) {
return stack->top == MAX_SIZE - 1;
}
// 入栈操作
bool push(ArrayStack* stack, int value) {
if (isFull(stack)) {
return false; // 栈满,入栈失败
}
stack->data[++stack->top] = value;
return true;
}
// 出栈操作
bool pop(ArrayStack* stack, int* value) {
if (isEmpty(stack)) {
return false; // 栈空,出栈失败
}
*value = stack->data[stack->top--];
return true;
}
// 获取栈顶元素
bool peek(ArrayStack* stack, int* value) {
if (isEmpty(stack)) {
return false; // 栈空,获取失败
}
*value = stack->data[stack->top];
return true;
}
链表实现
typedef struct StackNode {
int data;
struct StackNode* next;
} StackNode;
typedef struct {
StackNode* top; // 栈顶指针
} LinkedStack;
// 初始化栈
void initStack(LinkedStack* stack) {
stack->top = NULL;
}
// 判断栈是否为空
bool isEmpty(LinkedStack* stack) {
return stack->top == NULL;
}
// 入栈操作
void push(LinkedStack* stack, int value) {
StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
if (newNode == NULL) {
printf("内存分配失败\n");
return;
}
newNode->data = value;
newNode->next = stack->top;
stack->top = newNode;
}
// 出栈操作
bool pop(LinkedStack* stack, int* value) {
if (isEmpty(stack)) {
return false; // 栈空,出栈失败
}
StackNode* temp = stack->top;
*value = temp->data;
stack->top = temp->next;
free(temp);
return true;
}
// 获取栈顶元素
bool peek(LinkedStack* stack, int* value) {
if (isEmpty(stack)) {
return false; // 栈空,获取失败
}
*value = stack->top->data;
return true;
}
二、队列(Queue)基础
1. 基本概念
- 队列是一种遵循先进先出(FIFO, First In First Out)原则的线性数据结构
- 只允许在一端(队尾)进行插入操作,在另一端(队头)进行删除操作
- 基本操作:enqueue(入队)、dequeue(出队)、peek/front(查看队头元素)
2. 队列的实现方式
数组实现(循环队列)
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int front; // 队头指针
int rear; // 队尾指针
int size; // 当前队列大小
} CircularQueue;
// 初始化队列
void initQueue(CircularQueue* queue) {
queue->front = 0;
queue->rear = 0;
queue->size = 0;
}
// 判断队列是否为空
bool isEmpty(CircularQueue* queue) {
return queue->size == 0;
}
// 判断队列是否已满
bool isFull(CircularQueue* queue) {
return queue->size == MAX_SIZE;
}
// 入队操作
bool enqueue(CircularQueue* queue, int value) {
if (isFull(queue)) {
return false; // 队列已满,入队失败
}
queue->data[queue->rear] = value;
queue->rear = (queue->rear + 1) % MAX_SIZE; // 循环队列
queue->size++;
return true;
}
// 出队操作
bool dequeue(CircularQueue* queue, int* value) {
if (isEmpty(queue)) {
return false; // 队列为空,出队失败
}
*value = queue->data[queue->front];
queue->front = (queue->front + 1) % MAX_SIZE; // 循环队列
queue->size--;
return true;
}
// 获取队头元素
bool peek(CircularQueue* queue, int* value) {
if (isEmpty(queue)) {
return false; // 队列为空,获取失败
}
*value = queue->data[queue->front];
return true;
}
链表实现
typedef struct QueueNode {
int data;
struct QueueNode* next;
} QueueNode;
typedef struct {
QueueNode* front; // 队头指针
QueueNode* rear; // 队尾指针
} LinkedQueue;
// 初始化队列
void initQueue(LinkedQueue* queue) {
queue->front = NULL;
queue->rear = NULL;
}
// 判断队列是否为空
bool isEmpty(LinkedQueue* queue) {
return queue->front == NULL;
}
// 入队操作
void enqueue(LinkedQueue* queue, int value) {
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
if (newNode == NULL) {
printf("内存分配失败\n");
return;
}
newNode->data = value;
newNode->next = NULL;
if (isEmpty(queue)) {
queue->front = newNode;
queue->rear = newNode;
} else {
queue->rear->next = newNode;
queue->rear = newNode;
}
}
// 出队操作
bool dequeue(LinkedQueue* queue, int* value) {
if (isEmpty(queue)) {
return false; // 队列为空,出队失败
}
QueueNode* temp = queue->front;
*value = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL; // 队列变为空
}
free(temp);
return true;
}
// 获取队头元素
bool peek(LinkedQueue* queue, int* value) {
if (isEmpty(queue)) {
return false; // 队列为空,获取失败
}
*value = queue->front->data;
return true;
}
三、栈的经典面试题
1. 有效的括号匹配
问题:给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
思路:使用栈来匹配括号,遇到左括号入栈,遇到右括号时与栈顶元素匹配。
bool isValid(char* s) {
int len = strlen(s);
if (len % 2 != 0) return false; // 奇数长度一定不匹配
char stack[len];
int top = -1;
for (int i = 0; i < len; i++) {
if (s[i] == '(' || s[i] == '{' || s[i] == '[') {
// 左括号入栈
stack[++top] = s[i];
} else {
// 右括号,检查栈是否为空
if (top == -1) return false;
// 检查是否匹配
if ((s[i] == ')' && stack[top] != '(') ||
(s[i] == '}' && stack[top] != '{') ||
(s[i] == ']' && stack[top] != '[')) {
return false;
}
// 匹配成功,弹出栈顶元素
top--;
}
}
// 栈为空表示所有括号都匹配
return top == -1;
}
2. 用栈实现队列
问题:使用栈实现队列的下列操作:push、pop、peek、empty。
思路:使用两个栈,一个用于入队(pushStack),一个用于出队(popStack)。
typedef struct {
int* pushStack;
int pushTop;
int* popStack;
int popTop;
int capacity;
} MyQueue;
// 创建队列
MyQueue* myQueueCreate(int capacity) {
MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
queue->pushStack = (int*)malloc(sizeof(int) * capacity);
queue->popStack = (int*)malloc(sizeof(int) * capacity);
queue->pushTop = -1;
queue->popTop = -1;
queue->capacity = capacity;
return queue;
}
// 将元素从pushStack移动到popStack
void transfer(MyQueue* queue) {
if (queue->popTop == -1) { // 只有当popStack为空时才转移
while (queue->pushTop != -1) {
queue->popStack[++queue->popTop] = queue->pushStack[queue->pushTop--];
}
}
}
// 入队操作
void myQueuePush(MyQueue* queue, int x) {
queue->pushStack[++queue->pushTop] = x;
}
// 出队操作
int myQueuePop(MyQueue* queue) {
transfer(queue);
if (queue->popTop == -1) {
return -1; // 队列为空
}
return queue->popStack[queue->popTop--];
}
// 获取队头元素
int myQueuePeek(MyQueue* queue) {
transfer(queue);
if (queue->popTop == -1) {
return -1; // 队列为空
}
return queue->popStack[queue->popTop];
}
// 判断队列是否为空
bool myQueueEmpty(MyQueue* queue) {
return (queue->pushTop == -1 && queue->popTop == -1);
}
// 释放队列
void myQueueFree(MyQueue* queue) {
free(queue->pushStack);
free(queue->popStack);
free(queue
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
【秋招】嵌入式八股文最全总结 文章被收录于专栏
双非本,211硕。本硕均为机械工程,自学嵌入式,在校招过程中拿到小米、格力、美的、比亚迪、海信、海康、大华、江波龙等offer。八股文本质是需要大家理解,因此里面的内容一定要详细、深刻!这个专栏是我个人的学习笔记总结,是对很多面试问题进行的知识点分析,专栏保证高质量,让大家可以高效率理解与吸收里面的知识点!掌握这里面的知识,面试绝对无障碍!
