一、栈的基本概念
栈是一种特殊的线性表,其操作限制在固定的一端(栈顶)。这种结构遵循后进先出(LIFO)原则,常见于堆叠的盘子、函数调用等场景。关键术语包括:
- 栈顶:允许插入和删除的一端。
- 栈底:栈顶的对端。
- 入栈(push):向栈顶插入元素。
- 出栈(pop):从栈顶移除元素。
- 取栈顶(top):获取栈顶元素但不移除。
栈的存储形式
栈的实现可分为顺序栈和链式栈:
顺序栈
通过数组实现,需预先分配连续内存空间。结构体定义如下:
typedef struct {
datatype *data; // 存储数组
int size; // 栈容量
int top; // 栈顶下标(初始为-1)
} seqStack;
链式栈
通过链表实现,动态分配节点内存。结构体定义如下:
typedef struct node {
datatype data;
struct node *next;
} node;
typedef struct {
node *top; // 栈顶指针
int size; // 元素个数
} linkStack;
基本操作实现
顺序栈操作
// 初始化栈
seqStack *initStack(int size) {
seqStack *s = malloc(sizeof(seqStack));
if (s) {
s->data = malloc(sizeof(datatype) * size);
s->size = size;
s->top = -1;
}
return s;
}
// 入栈
bool push(seqStack *s, datatype data) {
if (s->top == s->size - 1) return false;
s->data[++s->top] = data;
return true;
}
// 出栈
bool pop(seqStack *s, datatype *pm) {
if (s->top == -1) return false;
*pm = s->data[s->top--];
return true;
}
链式栈操作
// 初始化栈
linkStack *initStack() {
linkStack *s = malloc(sizeof(linkStack));
if (s) {
s->top = NULL;
s->size = 0;
}
return s;
}
// 入栈
bool push(linkStack *s, datatype data) {
node *newNode = malloc(sizeof(node));
if (!newNode) return false;
newNode->data = data;
newNode->next = s->top;
s->top = newNode;
s->size++;
return true;
}
// 出栈
bool pop(linkStack *s, datatype *pm) {
if (!s->top) return false;
node *tmp = s->top;
*pm = tmp->data;
s->top = tmp->next;
free(tmp);
s->size--;
return true;
}
关键区别
- 顺序栈:内存连续,容量固定,适合已知最大规模的场景。
- 链式栈:动态扩容,内存分散,适合规模不确定的场景。
应用场景
- 函数调用栈
- 表达式求值(如括号匹配)
- 浏览器历史记录(后退功能)
二、队列的基本概念
队列是一种特殊的线性表,遵循先进先出(FIFO)原则。只能在固定两端操作:
- 队头:删除节点的一端
- 队尾:插入节点的一端
- 入队(
enQueue()):在队尾插入节点 - 出队(
outQueue()):从队头删除节点 - 取队头(
front()):获取队头元素但不删除
循环队列(顺序存储)
循环队列通过顺序存储实现,利用数组的循环利用特性避免数据移动。需牺牲一个存储单元区分空队和满队:
- 空队条件:
front == rear - 满队条件:
(rear + 1) % capacity == front
管理结构体示例
struct seqQueue {
datatype *data; // 数组入口
int capacity; // 总容量
int front; // 队头下标
int rear; // 队尾下标
};
核心操作代码
// 初始化
seqQueue* initQueue(int cap) {
seqQueue *q = malloc(sizeof(seqQueue));
q->data = malloc(cap * sizeof(datatype));
q->capacity = cap;
q->front = q->rear = 0;
return q;
}
// 入队
bool enQueue(seqQueue *q, datatype val) {
if ((q->rear + 1) % q->capacity == q->front)
return false;
q->data[q->rear] = val;
q->rear = (q->rear + 1) % q->capacity;
return true;
}
// 出队
bool outQueue(seqQueue *q, datatype *val) {
if (q->front == q->rear)
return false;
*val = q->data[q->front];
q->front = (q->front + 1) % q->capacity;
return true;
}
链式队列
链式队列通过链表实现,管理结构体保存队头、队尾指针及元素数量:
结构体定义
typedef struct node {
datatype data;
struct node *next;
} node;
typedef struct {
node *front; // 队头指针
node *rear; // 队尾指针
int size; // 元素数量
} linkQueue;
核心操作代码
// 入队
bool enQueue(linkQueue *q, datatype val) {
node *newNode = malloc(sizeof(node));
newNode->data = val;
newNode->next = NULL;
if (q->size == 0)
q->front = q->rear = newNode;
else {
q->rear->next = newNode;
q->rear = newNode;
}
q->size++;
return true;
}
// 出队
bool outQueue(linkQueue *q, datatype *val) {
if (q->size == 0)
return false;
*val = q->front->data;
node *tmp = q->front;
q->front = q->front->next;
free(tmp);
q->size--;
if (q->size == 0)
q->rear = NULL;
return true;
}

被折叠的 条评论
为什么被折叠?



