栈和队列的应用&特殊矩阵的压缩存储

栈的应用

(1)栈在括号匹配中的应用

遇到左括号则把左括号压入栈底,遇到右括号,则把栈顶元素弹出

(栈中还有左括号,而没有右括号与其匹配,则说明匹配失败

如果右括号还有没有被匹配到的,而左括号已经空,说明匹配失败)

const int maxsize = 10;//定义栈中元素的最大个数
typedef struct {
    char data[maxsize];//静态数组存放栈中元素
    int top;//栈顶指针
}sqstack;

//初始化栈
void initstack(sqstack& s);

//判断栈是否为空
bool stackempty(sqstack& s);

//新元素入栈
bool push(sqstack& s,char x);

//栈顶元素
bool pop(sqstack& s,char&x);
bool check(char stl[], int length) {
    sqstack s;
    initstack(s);
    for (int i = 0; i < length; i++) {
        if (stl[i] == '(' || stl[i] == '[' || stl[i] == '{') {
            push(s,stl[i]);
        }
        else {
            if (stackempty(s))return 0;
        }
        char topelem;
        pop(s, topelem);
        if (stl[i] == ')' && topelem != '(')return false;

        if (stl[i] == '[' && topelem != ']')return false;

        if (stl[i] == '{' && topelem != '}')return false;

    }
    return stackempty(s);
}

(2)表达式求值问题

1.中缀表达式:a+b,a+b-c,a+b-c*d

2.后缀表达式:ab+,ab+c-,ab+cd*-

3.前缀表达式:+ab,-+abc,-+ab*cd

(1)将中缀表达式转化为后缀表达式遵循左优先原则

后缀表达式的计算:从左往右扫描,每遇到一个运算符,就让运算符前面最近的两个操作数执行运算,合体为一个操作数

用栈实现后缀表达式的计算:

1.从左往右扫描下一个元素,直到处理完所有元素

2.若扫描到操作数则压入栈,并回到 1 否者执行 3 

3.若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压入栈顶,回到 1 

(2)将中缀转前缀遵循右优先原则

用栈实现后缀表达式的计算:

1.从右往左扫描下一个元素,直到处理完所有元素

2.若扫描到操作数则压入栈,并回到 1 否者执行 3 

3.若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压入栈顶,回到 1 

(3)在递归中的应用

函数调用栈

把操作压入栈中遵循先进后出后进先出

递归调用栈

每进入一层递归,就将递归信息压入栈顶

每退出一层递归,就从栈顶弹出相应信息

递归层数太深可能会导致栈溢出

队列的应用

(1)树的层次遍历

树的层次遍历需要用队列进行辅助,将树的衍生节点放到队尾

(2)图的广度优先遍历

 将与当前节点相邻且没有被操作过的节点放入队列中,当相邻节点都处理过之后,就可以将当前节点出队

(3)操作系统中的应用

“先来后到的原则”

特殊矩阵的压缩存储

(1)一维数组

线性储存

(2)二维数组

连续的储存空间中行优先或者列优先

你可能感兴趣的:(数据结构)