栈
栈的存储结构:
顺序栈
typedef struct SqStack
{
    int data[maxSize];
    int top;
}SqStack;链式栈
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;::栈的本质是线性表::,和线性表的定义方式完全一样!
顺序栈
四要素:两状态+两操作
- 
几个状态 - 空栈:st.top == -1//top 代表栈顶元素的index
- 满栈:st.top == maxSize-1
- 非法上下溢
 
- 
两个基本操作 - 进栈:先移动指针,再进入元素
 
stack[++top] = x;- 出栈:先取出元素,后移动指针
x = stack[top--];::用前先判断,空时不出,满时不进!::
链栈
四要素:两状态+两操作
- 
两个状态 - 空栈:lst->next == NULL
- 满栈:不存在这种情况
 
- 
两个基本操作 - 
进栈:头插法 
 ::头结点原来是指向的栈顶啊!!!::
- 
出栈:出栈元素保存到x中 
 
- 
p = lst->next;
x = p->data;
lst->next = p->next;
free(p);::考试不用写栈的函数,直接写必要的语句!::
习题
- 编写算法,判断一个表达式中括号是否真确配对,表达式个数为n
int match(char exp[], int n){
    //初始化栈
    char stack[maxSize];
    int top = -1;
    for(int i = 0; i < n; ++i){
        if(exp[i] == '(')
        stack[++top] = '(';
        if(exp[i] == ')'){
            if(top == -1)
            return 0;
            else 
            --top;
        }
    }
    if(top == -1)
    return 1;
    else
    return 0;
}::栈中只放左括号!然后看到右括号就出栈::
- 编写一个函数,求后缀式的数值,其中后缀式存于字符数组exp中,exp中最后一个‘/0’作为结束符,并假设后缀式中的数字都只有一位。
//先定义操作符
int op(int a, char op, int b){
    if(op == '+') return a + b;
    if(op == '-') return a - b;
    if(op == '*') return a * b;
    if(op == '/'){
        if(b == 0){
            std::cout<<"b不能为0!"<<endl;
            return 0;
        }
        else return a/b;
    }
}
//再定义后缀计算函数
int com(char exp[]){
    int stack[maxSize];
    int top == -1;
    int a, b, c;
    char op;
    for(int i = 0; exp[i] != '/0'; ++i){
        if(exp[i] >= '0' && exp[i] <= '9')
        stack[++top] = exp[i] - '0';
        else{
            op = exp[i];
            b = stack[top--];
            a = stack[top--];
            c = op(a, op, b);
            stack[++top] = c;
        }
    }
    return stack[top];
}队列
队列的存储结构
顺序队
typedef struct SqQueue
{
    int data[maxSize];
    int front;
    int rear;
}SqQueue;链队
//队结点类型定义
typedef struct QNode
{
    int data;
    struct QNode *next;
}QNode;
//队类型定义
typedef struct LiQueue
{
    QNode *front;
    QNode *rear;
}LiQueue;顺序队
使用传统的顺序队列会产生“假溢出”情况,我们一般使用循环队列。 
当元素进队时,rear指针向后移动; 
当元素出队时,front指针向前移动。
- 
两状态 - 队空状态:qu.rear == qu.front
- 队满状态:(qu.rear + 1)%maxSize == front
 
- 
两操作 - 元素x进队:
 
qu.rear == (qu.rear + 1)%maxSize;
qu.data[qu.rear] = x;- 元素x出队:
qu.front == (qu.front + 1)%maxSize;
x = qu.data[qu.front];::都是先移动指针,后存取数据。::
链队
不存在“假溢出”。
- 
两状态 - 队空状态:lqu->rear == NULL || lqu->front == NULL
- 不存在队满状态
 
- 
两操作 - 入队:
 
lqu->rear->next = p;
lqu->rear = p;- 出队:
p = lqu->front;
lqu->front = lqu->front->next;
x = p->data;
free(p);::顺序队比链队简单多了,要尽量用顺序队。::
总习题
- 
设循环队列的下标范围是0~n-1,其头、尾指针分别为f和r,则其元素个数为 (r - f + n)%n 
 - 当r > f 时,队列内元素为r - f;
- 当r < f 时,队列内元素为n - ( f - r )
 
- 
编写一个算法,将一个非负的十进制整数N转换为一个二进制数。 
int BaseTrans(int N){
    int i, result = 0;
    int stack[maxSize], top = -1;
    while(N != 0){
        i = N % 2;
        N = N / 2;
        stack[++top] = i;
    }
    while(top != -1){
        i = stack[top--];
        result = result * 10 + i;
    }
    return result;
}