思维导图:点我
一、栈
1. 顺序栈
-
存储结构
#define MaxSize 10 typedef struct { ElemType data[MaxSize]; int top; } SqStack;
-
初始化
void InitStack(SqStack &S) { S.top=-1; }
-
判栈空
bool StackEmpty(SqStack S) { if(S.top==-1) return true; else return false; }
-
进栈
bool Push(SqStack &S,ElemType e) { if(S.top==MaxSize-1) return false; S.data[++S.top]=e; return true; }
-
出栈
bool Pop(SqStack &S,ElemType &e) { if(S.top==-1) return false; e=S.data[top--]; return true; }
-
读栈顶元素
bool GetTop(SqStack S,ElemType &e) { if(S.top==-1) return false; e=S.data[top]; return true; }
2. 共享栈
在一段连续空间首和尾各开辟一个栈,top1=-1时1号栈为空,top2=MaxSize时2号栈为空,当两个栈顶指针相邻时两个栈满
3. 带头结点的链栈
-
存储结构
typedef struct Linknode { ElemType data; struct Linknode *next; } LNode,*LiStack;
-
初始化
bool InitStack(LiStack &p) { p=(LNode *)malloc(sizeof(LNode)); p->next=NULL; return true; }
-
进栈
bool Push(LiStack &p,ElemType e) { if(p==NULL) return false; LNode *s=(LNode *)malloc(sizeof(LNode)); s->data=e; s->next=p->next; p->next=s; return true; }
-
出栈
bool Pop(LiStack &p,ElemType &e) { if(p==NULL||p->next==NULL) return false; LNode *s=p->next; e=s->data; p=s->next; free(s); return true; }
-
判栈空
bool StackEmpty(LiStack p) { if(p==NULL) return false; if(p->next==NULL) return true; else return false; }
-
读栈顶元素
bool GetTop(LiStack p, ElemType &e) { if(p==NULL||p->next==NULL) return false; e=p->next->data; return true; }
4. 不带头结点的链栈
-
存储结构
typedef struct Linknode { ElemType data; struct Linknode *next; } LNode,*LiStack;
-
进栈
bool Push(LiStack &p,ElemType e) { if(p==NULL) { p=(LNode *)malloc(sizeof(LNode)); p->data=e; p->next=NULL; } else { LNode *s=(LNode *)malloc(sizeof(LNode)); s->data=e; s->next=p; p=s; } return true; }
-
出栈
bool Pop(LiStack &p,ElemType &e) { if(p==NULL) return false; else { LNode *s=p->next; e=p->data; free(p); p=s; } return true; }
-
判栈空
bool StackEmpty(LiStack p) { if(p==NULL) return true; else return false; }
-
读栈顶元素
bool GetTop(LiStack p, ElemType &e) { if(p==NULL) return false; e=p->data; return true; }
二、栈的应用
1. 括号匹配
2. 表达式求值
-
中缀表达式与前后缀表达式的互化
中缀表达式化后缀表达式遵循左优先,化前缀表达式遵循右优先
-
构造后缀表达式
使用符号栈
-
后缀表达式求值
使用符号栈与数据栈
3. 递归
-
原理
即我自己调用我自己
-
应用
斐波那契数列
-
应用原理
系统为每一层的返回点、局部变量、传入实参等开辟了递归工作栈来进行数据存储。
三、队列
1. 顺序队列
-
存储结构
#define MaxSize 10 typedef struct Linknode { ElemType data[MaxSize]; int front,rear; } SqQueue;
-
初始化
void InitQueue(SqQueue &Q) { Q.front=Q.rear=0; }
-
入队
bool EnQueue(SqQueue &Q,ElemType e) { if(Q.rear==MaxSize-1) return false; Q.data[Q.rear++]=e; return true; }
-
出队
bool DeQueue(SqQueue &Q,ElemType &e) { if(Q.rear==Q.front) return false; e=Q.data[Q.front++]; return true; }
-
队列判空
bool QueueEmpty(SqQueue Q) { if(Q.front==Q.rear) return true; else return false; }
-
读队头元素
bool GetHead(SqQueue Q,ElemType &e) { if(Q.rear==Q.front) return false; e=Q.data[Q.front]; return true; }
2. 循环队列
-
存储结构
#define MaxSize 10 typedef struct Linknode { ElemType data[MaxSize]; int front,rear; } SqQueue;
-
初始化
void InitQueue(SqQueue &Q) { Q.front=Q.rear=0; }
-
入队
bool EnQueue(SqQueue &Q,ElemType e) { if((Q.rear+1)%MaxSize==Q.front) return false; Q.data[Q.rear]=e; Q.rear=(Q.rear+1)%MaxSize; return true; }
-
出队
bool DeQueue(SqQueue &Q,ElemType &e) { if(Q.rear==Q.front) return false; e=Q.data[Q.front]; Q.front=(Q.front+1)%MaxSize; return true; }
-
队列判空
bool QueueEmpty(SqQueue Q) { if(Q.front==Q.rear) return true; else return false; }
-
读队头元素
bool GetHead(SqQueue Q,ElemType &e) { if(Q.rear==Q.front) return false; e=Q.data[Q.front]; return true; }
3. 链队
-
存储结构
#define MaxSize 10 typedef struct LinkNode { ElemType data; struct LinkNode *next; } LinkNode; typedef struct { LinkNode *front,*rear; } LinkQueue;
-
初始化
void InitQueue(LinkQueue &Q) { Q.front=Q.rear=(LinkNode *)malloc(sizeof(LinkNode)); Q.front->next=NULL; }
-
入队
bool EnQueue(LinkQueue &Q,ElemType e) { LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode)); s->data=e; s->next=NULL; Q.rear->next=s; Q.rear=s; return true; }
-
出队
bool DeQueue(LinkQueue &Q,ElemType &e) { if(Q.front==Q.rear) return false; LinkNode *s=Q.front->next; e=s->data; Q.front->next=s->next; if(s==Q.rear) Q.rear=Q.front; free(s); return true; }
-
队列判空
bool IsEmpty(LinkQueue Q) { if(Q.front==Q.rear) return true; else return false; }
-
读队头元素
bool GetHead(LinkQueue Q,ElemType &e) { if(Q.front==Q.rear) return false; e=Q.front->next->data; return true; }
4. 双端队列
-
普通双端队列
两端皆可入队出队
-
输出受限的双端队列
队头可入队出队,队尾只能入队
-
输入首先的双端队列
对头可入队出队,队尾只能出队
四、队列的应用
1. 层次遍历
-
树的层次遍历
详见 《树》
-
图的层次遍历
详见 《图》
2. 计算机中的应用
-
任务队列
详见 《操作系统》
-
进程队列
详见 《操作系统》
-
流量控制窗口
详见 《计算机网络》