⚡第三章栈和队列⚡

一.

如图:

栈(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 +

以上图片均来自王道数据结构书中

仅为个人复习方便所写,如有侵权立即删除!

posted @ 2020-07-04 16:15  xiaoff  阅读(228)  评论(0编辑  收藏  举报