数据结构与算法2
栈 队列 串
1.栈(stack)
1.1 栈的定义和特点
- 栈是一个特殊的线性表,仅在表尾进行插入和删除
- 后进先出的线性表(LIFO结构)
表尾(an端)称为栈顶TOP;表头(a1端)称为栈底BASE
- 入栈:插入元素到TOP
- 出栈:从TOP删除最后一个元素
同线性表相同,为一对一关系
-
存储结构:顺序栈、链栈
- 栈的顺序存储:顺序栈
- 栈的链式存储:链栈
-
上溢(overflow):栈已经满,继续压入值
-
下溢(underflow):栈已经空,继续弹出值
上溢是一种错误,使问题处理无法进行
下溢使一种结束条件,问题处理结束
1.2 顺序栈的表示
#define MAXSIZE 100
typedef struct{
int *base; //栈底
int *top; //栈顶
int stacksize; //栈可用的最大容量
}SqStack;
1.3 顺序栈的实现
1.3.1 顺序栈的初始化
void InitStack(SqStack &S){ //构建一个空顺序栈
S.base = new int[MAXSIZE];
if(!S.base) return; //存储分配失败
S.top = S.base;
S.stacksize = MAXSIZE;
}
1.3.2 顺序栈判断栈是否为空
bool StackEmpty(SqStack S){ //若栈顶等于栈底,则顺序栈为空
if(S.top == S.base) return true;
else return false;
}
1.3.3 求顺序栈长度
int StackLength(SqStack S){
return S.top - S.base;
}
1.3.4 清空顺序栈
void ClearStack(SqStack &S){
if(S.base) S.top = S.base;
}
1.3.5 销毁顺序栈
void DestoryStack(SqStack &S){
if(S.base){
delete S.base;
S.stacksize = 0;
S.base = S.top = NULL;
}
}
1.3.6 顺序栈的入栈
void Push(SqStack &S, int e){
if(S.top - S.base == S.stacksize) return; //栈满
*S.top++ = e; //等价于*S.top = e; S.top++;
}
1.3.7 顺序栈的出栈
void Pop(SqStack &S, int &e){
if(S.top == S.base) return;
e = *--S.top; //同上述
}
1.4 栈链的表示
- 运算受限的单链表,只能在链表头部进行操作
- 链表的头指针就是栈顶,不需要头结点
- 插入删除仅在栈顶
typedef struct StackNode{
int data;
struct StackNode *next;
}StackNode, *LinkStackPtr;
typedef struct LinkStack{
LinkStackPtr top;
`int count;
}LinkStack;
1.5 栈链的实现
1.5.1 栈链的初始化
void InitStack(LinkStack *&S){
S->top = NULL;
S->count = 0;
}
1.5.2 判断栈链是否为空
bool StackEmpty(LinkStack *S){
if(S->top == NULL) return true;
else return false;
}
1.5.3 栈链的入栈
void Push(LinkStack *&S, int e){
LinkStackPtr p = new StackNode; //生成新节点
p->data = e;
p->next = S->top;
S->top = p;
S->count++;
}
1.5.4 栈链的出栈
void Pop(LinkStack *&S, int &e){
if(S->top == NULL) return;
e = S->top->data; //出栈的元素值
LinkStackPtr p = S->top;
S->top = S->top->next;
delete p;
S->count--;
}
1.5.5 取栈顶元素
int GetTop(LinkStack *S){
if(S->top == NULL) return;
return S->data;
}
2.队列(queue)
2.1 队列的定义和特点
- 队列是一种先进先出(FIFO)的线性表
- 在表尾插入,表头删除(头删尾插)
- 表尾为an端(队尾),表头为a1端(队头)
同线性表相同,为一对一关系
- 存储结构:顺序队、链队
循环顺序队列更常见
2.2 顺序队的表示(包括循环队列操作,自行区分)
#define MAXQSIZE 100 //最大队列长度
typedef define{
int *base; //初始化动态分配原始空间
int front; //头指针
int rear; //尾指针 尾指针指向元素的下一个位置
}SqQueue;
2.3 顺序队的实现
常见问题:假上溢
解决方法:引入循环队列 实现方式:使用模运算
- 插入元素: Q.base[Q.rear] = x; Q.rear=(Q.rear+1) % MAXQSIZE;
- 删除元素: x = Q.base[s.front]; Q.front = (Q.front+1) % MAXQSIZE;
2.3.1 顺序队的初始化
void Init(sqQueue &q){
q.base = new int(MAXQSIZE); //为顺序队分配空间
if(!q.base) return;
q.front = q.rear = 0; //表示队空
}
2.3.2 销毁顺序队
void Destory(sqQueue &q){
delete q.base;
q.base = NULL;
}
2.3.3 返回顺序队长
int SqLength(SqQueue q){
if(q.rear >= q.front)
return q.rear-q.front+1
else
return MAXQSIZE-q.front+q.rear+1;
}
2.3.4 顺序队入队
void EnterSq(sqQueue &q, int e){
if((q.rear+1)%MAXQSIZE == q.front) return;
q.base[q.rear] = e;
q.rear = (q.rear+1)%MAXQSIZE;
}
2.3.5 顺序队出队
void DeleteSq(sqQueue &q, int &e){
e = q.base[q.front];
q.front = (q.front+1)%MAXQSIZE;
}
2.4 队列的链式存储结构
- 实质是线性表的单链表
- 只能尾进头出
- 简称为链队列
对头指针指向链队列头结点 队尾指针指向链队列终端节点
空队列时,front和rear都指向头结点
2.5 链队列的表示
typedef struct QNode{ //结点结构
int data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{ //队列的链式结构
QueuePtr front, rear; //队头队尾指针
}LinkQueue;
2.6 链队列的实现
2.6.1 链队列的入队
void EnQueue(LinkQueue *&Q, int e){
QueuePtr s = new QNode;
if(!s) //存储失败
return;
s->data = e;
s->next = NULL;
Q->rear->next = s;
Q->rear = s;
}
2.6.2 链队列的出队
void DeQueue(LinkQueue *&Q, int &e){
QueuePtr p;
if(Q->front == Q->rear) //注意判断队列是否为空
return;
p = Q->front->next;
e = p->data;
Q->front->next = p->next;
if(Q->rear == p)
Q.rear = Q->front;
delete p;
}
3. 串(string)
3.1 串的定义和特点
- 串是由零个或多个字符组成的有限序列,又名叫字符串
- 一般记为 s = "a1a2...an" (n >= 0)
- n为串的长度
- 零个字符的串称空串
3.2 串的比较
有两个串s="a1a2...an", t="b1b2...bm"
1. n < m, 且ai=bi(i=1,2,3...,n) 则s<t
2. 存在某个k<=min(m,n),使得ai=bi(i=1,2,3,...,k-1) 则s<t
3.3 串的模式匹配
- 暴力匹配法
- KMP算法
总结
- 栈是限定仅在尾表进行插入删除的线性表
- 队列是只允许在一端进行插入操作,而在另一端进行删除操作
程杰. 大话数据结构[M]. 北京:清华大学出版社, 2011:25.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南