栈和队列详解
目录
1.栈
1.1 概念与结构
1.2 栈的实现
2.队列
2.1 概念与结构
2.2 队列的实现
3.栈和队列算法题
3.1 有效的括号
3.2 用队列实现栈
3.3 用栈实现队列
3.4 设计循环列表
1.栈
1.1 概念与结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO的原则
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除操作叫做出栈。出数据也在栈顶
栈底层结构选型:
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小
1.2 栈的实现
Stack.h
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>typedef int STDataType;
//定义栈的数据结构
typedef struct Stack
{
STDataType* arr;
int top; //指向栈顶位置
int capacity; //容量
}ST;void STInit(ST* ps);
void STDestroy(ST* ps);//入栈--栈顶
void StackPush(ST* ps, STDataType x);
//出栈--栈顶
void StackPop(ST* ps);//取栈顶元素
STDataType StackTop(ST* ps);//栈是否为空
bool StackEmpty(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
Stack.c
#include"Stack.h"
//初始化
void STInit(ST* ps)
{
assert(ps);
ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//销毁
void STDestroy(ST* ps)
{
if (ps->arr != NULL)
free(ps->arr);ps->arr = NULL;
ps->top = ps->capacity = 0;
}
//入栈--栈顶
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
//空间满了--增容
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail\n");
exit(1);
}
ps->arr = tmp;
ps->capacity = newCapacity;
}
//空间足够
ps->arr[ps->top++] = x;
}
//栈是否为空
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
//出栈--栈顶
void StackPop(ST* ps)
{
assert(!StackEmpty(ps));
--ps->top;
}
//取栈顶元素
STDataType StackTop(ST* ps)
{
assert(!StackEmpty(ps));
return ps->arr[ps->top - 1];
}
//获取栈中有效元素个数
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
2.队列
2.1 概念与结构
概念:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
队列底层结构选项
2.2 队列的实现
Queue.h
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>typedef int QDataType;
//定义队列结点的结构
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QueueNode;
//定义队列的结构
typedef struct Queue
{
QueueNode* phead;//队头
QueueNode* ptail;//队尾
int size; //队列有效元素个数
}Queue;
//初始化
void QueueInit(Queue* pq);
//入队列--队头
void QueuePush(Queue* pq, QDataType x);
//队列判空
bool QueueEmpty(Queue* pq);
//队列有效元素个数
int QueueSize(Queue* pq);
//出队列--队头
void QueuePop(Queue* pq);
//取队头数据
QDataType QueueFront(Queue* pq);
//取队尾数据
QDataType QueueBack(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
Queue.c
#include"Queue.h"
//初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
//入队列--队头
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
{
perror("malloc fail!");
exit(1);
}
newnode->data = x;
newnode->next = NULL;//队列为空,队头和队尾都是newnode
if (pq->phead == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = pq->ptail->next;
}
pq->size++;
}
//队列判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
//队列有效元素个数
int QueueSize(Queue* pq)
{
//int size = 0;
//QueueNode* pcur = pq->phead;
//while (pcur)
//{
// size++;
// pcur = pcur->next;
//}
//return size;
return pq->size;
}
//出队列--队头
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
//只有一个结点
if (pq->phead == pq->ptail)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
else
{
//多个结点
QueueNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
--pq->size;
}
//取队头数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->phead->data;
}
//取队尾数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->ptail->data;
}
//销毁队列
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* pcur = pq->phead;
while (pcur)
{
QueueNode* next = pcur->next;
free(pcur);
pcur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
3.栈和队列算法题
3.1 有效的括号
https://leetcode.cn/problems/valid-parentheses/description/
3.2 用队列实现栈
https://leetcode.cn/problems/implement-stack-using-queues/description/
3.3 用栈实现队列
https://leetcode.cn/problems/implement-queue-using-stacks/description/
3.4 设计循环列表
https://leetcode.cn/problems/design-circular-queue/description/