⚡第三章栈和队列⚡
一.栈
如图:
栈(Stack)是只允许在一端进行插入或删除操作的线性表。
出栈元素不同排列的个数为 1/(n+1) C(2n,n)
栈顶指针:S.top
初始时设置S.top = -1
栈顶元素:S.data[S.top]。
进栈操作:找不满时,找顶指针先加1,再送值到栈顶元素。
出栈操作:栈非空时,先取栈顶元素值,再将栈顶指针减1。
栈空条件 :S.top == -1 栈满条件:S.top == MaxSize-1 栈长:S.top+l。
②进栈代码:
bool Push(SqStack &S,ElemType x){
if(S.top == MaxSize-1){ //栈满
return false;
}
S.data[++S.top] = x; //指针先加1,再入栈
return true;
}
③出栈代码:
bool Pop(SqStack &S,ElemType &x){
if(S.top == -1){ //栈空
return false;
}
x = S.data[S.top--]; //先出栈,指针再减1
return true;
}
⑤共享栈:
top0 = -1 0号栈为空
top1 = MaxSize 1号栈为空
top1-top0 = 1 栈满
链式栈不存在 栈满上溢的情况
小练习
判断操作序列是否合法
int Judge(char A[]){
//I代表入栈 O代表出栈
//合法含义是:栈的初态和终态都是空
int i;
int j=0,k=0; //i 为下标,j 和 k 分别为字母I和O的个数
whlie(A[i] != '\0'){
switch(A[i]){
case 'I': j++; break; //代表入栈 次数+1
case 'O': k++;
if(k > j){ //出栈数>入栈数
printf("非法!");
exit(0);
}
}
i++;
}
if(j != k){
printf("非法!");
return false;
}else{
printf("合法!");
return true;
}
}
二.队列
队列:只允许在表的一端进行插入,而在表的另一端进行删除
如图:
①入队出队操作示意图
②循环队列示意图
③队列各种条件
| 条件 | 条件 |
| ---- | ---- | ---- |
| 初始时 | Q.front = Q.rear=O |
| 入队 | Q.rear = (Q.rear+1)%MaxSize |
| 出队 | Q.front = (Q.front+1)%MaxSize |
| 队列长度 |(Q.rear+MaxSize-Q.front)%MaxSize|
④出入队代码:
//入队
bool EnQueue(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize == Q.front){
return false; //队满
}
Q.data[Q.rear] = x;
Q.rear = (Q.rear+1)%MaxSize; //队尾指针+1
return true;
}
//出队
bool DeQueue(SqQueue &Q,ElemType &x){
if(Q.rear+1 == Q.front){
return false; //队空
}
x = Q.data[Q.front];
Q.front = (Q.front+1)%MaxSize; //对头指针+1
return true;
}
⑤链式出入队
入队
//入队
void EnQueue(LinkQueue &Q,ElemType x){
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = x;
s->next = NULL;
Q.rear->next = s;
Q.rear = s;
}
//出队
bool DeQueue(LinkQueue &Q,ElemType &x){
if(Q.front == Q.rear){
return false;
}
LinkNode *p=Q.front->next;
x = p->data;
Q.front->next = p->next; //跨越p指针(删除操作)
if(Q.rear == p){
Q.rear = Q.front; //原队列只有一个节点,删除后变空
}
return true;
}
小练习
将队列中的元素逆置
void Reverse(Stack S,Queue Q){
while(!QueueEmpty(Q)){
x = DeQueue(Q); //依次出队
Push(x); //依次入栈
}
while(!StackEmpty(S)){
Pop(S,x); //依次出栈
EnQueue(Q,x); //依次入队
}
}
⑥双端队列
三.压缩矩阵
①对称矩阵
②三角矩阵
③三对角矩阵
④稀疏矩阵
三对角矩阵对应一位数组的位置公式为:K = 2i+j-3
二维数组计算地址公式:LOC(i,j) = LOC(0,0)+(i×m+j)×L
上述公式中:L代表每个数组元素的长度,m代表数组的列数。
表达式的转化
具体要求如下:
1.当前扫描到的元素'小于等于'栈顶元素,则栈顶元素出栈
2.遇到左括号直接入栈
3.遇到右括号做一系列的出栈(直到栈顶是左括号,并删除左括号)
例题:'a+b-a*((c+d)/e-f)+g'
中缀转后缀
a b + a c d + e / f - * - g +
以上图片均来自
王道数据结构
书中仅为个人复习方便所写,如有侵权立即删除!
由于时间有限,写的不好请见谅,理解万岁(: