目录
- 栈和队列,仍为线性表,是特殊的线性表;
一,栈
- 一种特殊的线性表,只允许在固定的一端进行插入和删除元素的操作;
- 进行数据插入和删除的一端为栈顶,另一端为栈低;
- 栈中的数据元素遵循后进先出LIFO的原则;
- 一种入栈顺序,可对应多种出栈顺序;
压栈:栈的插入操作,入数据到栈顶,叫做进栈、压栈、入栈;
出栈:栈的删除操作,出数据也在栈顶;
栈的实现
- 一般可使用数组和链表实现,相对而言数组更优;
- 数组尾插,代价较小;
//栈数组实现
//动态栈结构
typedef int STDataType;
typedef struct Stack
{
STDataType* data;
int top; //栈顶
int capacity; //容量
}Stack;
void StackInit(Stack* ps);
void StackDestroy(Stack* ps);
void StackPush(Stack* ps, STDataType x);
void StackPop(Stack* ps);
bool StackEmpty(Stack* ps);
int StackSize(Stack* ps);
STDataType StackTop(Stack* ps);
注:完整接口实现代码路径;
试题
二,队列
- 只允许在一端插入数据,另一端删除数据的特殊线性表;
- 队列具有先进先出FIFO原则;
- 一种入队顺序,只有一种出队顺序;
入队列:进行插入操作的一端称为队尾;
出队列:进行删除操作的一端称为队头;
队列的实现
- 一般可使用数组和链表实现,相对而言链表更优;
- 数组出队列,效率较低;
- 链表,头部出数据,尾部入数据;
//对列接口
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QueueNode;
//单链表不这样设计,是因为尾删时要记录前一个节点还是要遍历;
typedef struct Queue
{
QueueNode* phead;
QueueNode* ptail;
}Queue;
//队列初始化
void QueueInit(Queue* pq);
//队列释放
void QueueDestroy(Queue* pq);
//队列入数据,尾插
void QueuePush(Queue* pq, QDataType x);
//队列出数据,头删
void QueuePop(Queue* pq);
//返回队列头数据
QDataType QueueFront(Queue* pq);
//返回队列尾数据
QDataType QueueBack(Queue* pq);
//队列节点个数
int QueueSize(Queue* pq);
//是否为空队列
bool QueueEmpty(Queue* pq);
注:完整接口实现代码路径;
试题
循环队列
- 可使用数组实现,也可使用循环链表实现;
- 数据长度是固定的,使用动态顺序表实现更合适;
- 需额外多创建一个节点或空间,以判断空还是满;
- 使用单链表,取尾值时需获取rear的前一个,则要遍历链表;