数据结构-栈

    • 栈(Stack)
    • 栈顶和栈底
    • 栈的特性
    • 栈的存储结构
    • 顺序栈
    • 链栈
    • 栈的应用
    • CodeUp 1743

栈(Stack)

是一种限制存取点的线性表, 只能在一端进行插入或删除操作

栈顶和栈底

  • 栈顶: 指栈中允许进行插入和删除操作的一端
  • 栈底: 栈的另一端

栈的特性

典型的先入后出

栈的存储结构

  1. 顺序存储结构: 顺序栈
  2. 链式存储结构: 链栈

顺序栈

  1. 结构定义(相关宏定义参考线性表):

    typedef struct {
       ElemType data[MAX_SIZE]; //顺序存储, 先进后出
       int top;             //存栈顶位置(只能在栈顶一端插入或删除)
    }SqStack;
  2. 操作集:

    /* *初始化, 这里top存栈定元素的下一个位置, 同时也是栈的大小 */
    void initStack(SqStack &sq){
       sq.top = 0;
    }
    
    int size(SqStack &sq){   //栈大小
       return sq.top;
    }
    
    int isEmpty(SqStack sq){ //判栈是否为空
       return size(sq) == 0;
    }
    
    Status push(SqStack &sq, ElemType x){ //入栈
       if(sq.top == MAX_SIZE) return ERROR;
       sq.data[sq.top++] = x;
       return OK;
    }
    
    Status pop(SqStack &sq, ElemType &x){ //出栈
       if(isEmpty(sq)) return ERROR;
       x = sq.data[--sq.top];
       return OK;
    }
    
    Status top(SqStack sq, ElemType &x){  //获取栈顶元素
       if(isEmpty(sq)) return ERROR;
       x = sq.data[sq.top - 1];
       return OK;
    }
  3. 特点:

    • 有容量限制
    • 插入删除简单

链栈

  1. 结构定义:

    typedef struct LNode{
       ElemType data;       //数据域
       struct LNode * next;//指针域
    }LNode;
    /* * 一个头结点(不存储信息)指向表头 */
  2. 操作集:

    /* *新建结点 */
    LNode * newNode(ElemType x){
       LNode * res = (LNode *)malloc(sizeof(LNode));
       res->data = x;
       res->next = NULL;
       return res;
    }
    /* *插入操作, 这里栈顶第一个结点是表头的next指向的结点, 插入删除都在表头一端 *先入栈的元素在链表中后被删除(先进后出) *由于是链式结构, 所以一般没有容量限制, 插入操作都能够成功 */
    void push(LNode * head, ElemType x){
       LNode * tmp = newNode(x); 
       tmp->next = head->next;  //头插法
       head->next = tmp; 
    }
    
    int isEmpty(LNode * head){       //判空
       return head->next == NULL;
    }
    
    Status pop(LNode * head, ElemType x){
       if(isEmpty(head)) return ERROR; //栈为空
       LNode * tmp = head->next; //当前栈顶
       head->next = tmp->next;   //修改栈顶
       x = tmp->data;            //返回元素值
       free(tmp);               
       return OK;
    }
    
    Status top(LNode * head, ElemType &x){
       if(isEmpty(head)) return ERROR;
       x = head->next->data;
       return OK;
    }
  3. 特点

    • 无容量限制
    • 存储密度 < 1(指针域)

栈的应用

  • 后缀表达式求值
  • 函数调用时保护现场
  • 递归过程

CodeUp 1743

#include 
#include 
#include 
#include 
#define MAX_SIZE 100
#define Status int
#define OK 1
#define ERROR 0
#define ElemType Node
#define QElemType Node
/** *Sequence Stack **/
int prior[256];

void init(){
    prior['+'] = prior['-'] = 0;
    prior['*'] = prior['/'] = 1;
}

typedef struct{
    int v;
    int isOp;
}Node;

Node newNode(int _v, int _isOp){
    Node res;
    res.v = _v;
    res.isOp = _isOp;
    return res;
}

typedef struct{
    QElemType data[MAX_SIZE];
    int front;
    int rear;
}SqQueue;

void initQueue(SqQueue &sq){
    sq.front = sq.rear = 0;

}
Status Push(SqQueue &sq, QElemType x){
    if((sq.rear + 1) % MAX_SIZE == sq.front) return ERROR;
    sq.data[sq.rear++] = x;
    return OK;
}

int IsEmpty(SqQueue sq){
    return sq.front == sq.rear;
}

Status Pop(SqQueue &sq){
    if(sq.front == sq.rear) return ERROR;
    sq.front = (sq.front + 1) % MAX_SIZE;
    return OK;
}

QElemType front(SqQueue sq){
    return sq.data[sq.front];
}

typedef struct{
    ElemType data[MAX_SIZE];
    int top;
}SqStack;

void initStack(SqStack &sq){
    sq.top = 0;
}

int size(SqStack sq){
    return sq.top;
}

int isEmpty(SqStack sq){
    return size(sq) == 0;
}

Status push(SqStack &sq, ElemType x){
    if(sq.top == MAX_SIZE) return ERROR;
    sq.data[sq.top++] = x;
    return OK;
}

Status pop(SqStack &sq){
    if(isEmpty(sq)) return ERROR;
    --sq.top;
    return OK;
}

ElemType top(SqStack sq){
    return sq.data[sq.top - 1];
}

int isNum(char ch){
    return ch >= '0' && ch <= '9';
}

void dealWithOperator(SqStack &sta, SqQueue &sq, char op){
    if(op == '(' || op == ')'){
        if(op == '(') push(sta, newNode(op, 1));
        else{
            while(top(sta).v != '('){
                Push(sq, top(sta));
                pop(sta);
            }
            pop(sta);
        }
        return;;
    }
    while(!isEmpty(sta) && top(sta).v != '(' && prior[op] <= prior[top(sta).v]){
            Push(sq, top(sta));
            pop(sta);
    }
    push(sta, newNode(op, 1));
}

double cal(double a, double b, int op){
    if(op == '+') return a + b;
    if(op == '-') return a - b;
    if(op == '*') return a * b;
    if(op == '/') return a / b;
}

int main(){
// freopen("in.txt", "r", stdin);
    SqStack sta;
    SqQueue sq;
    init();
    initQueue(sq);
    initStack(sta);
    char str[50];
    char op = 0;
    while(scanf("%s", str) != EOF){
        int inNum = 0;
        int num = 0;
        for(int i = 0; str[i]; ++i){
            if(isNum(str[i])){
                if(inNum == 0) inNum = 1;
                num = 10 * num + str[i] - '0';
            }else{
                if(inNum == 1){
                    Push(sq, newNode(num, 0));
                    num = 0;
                    inNum = 0;
                }
                if(str[i] != '#')dealWithOperator(sta, sq, str[i]);
            }
        }
        while(!isEmpty(sta)){
            ElemType cur = top(sta);
            Push(sq, top(sta));
            pop(sta);
        }
        std::stack<double> res;
        while(!IsEmpty(sq)){
            QElemType cur = front(sq);
            if(cur.isOp == 1){
                double op2 = res.top();
                res.pop();
                double op1 = res.top();
                res.pop();
                res.push(cal(op1, op2, cur.v));
            }else res.push(cur.v);
            Pop(sq);
        }
        printf("%.0f\n", res.top());
    }
    return 0;
}

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