数据结构与算法实战 3.2.栈(青岛大学 周强)

  1 #include<iostream>
  2 
  3 using namespace std;
  4 
  5 //栈的操作:初始化 push(插入) pop(弹栈,注意有的语言里的栈pop的时候会顺便返回top元素) top(看栈顶元素) 
  6 //用数组做栈,如果以起始位置作为栈顶的话,操作时候会引起大量数据的移动,不划算
  7 //所以在用数组做栈的时候,会以末尾作为栈顶,起始位置作为栈底 
  8 //用链表做栈的时候,显然是与表头操作比较方便,所以链栈会用头作为栈顶 
  9 //C++ 中用stack利用栈 JAVA中用 Stack这个类 
 10 /*
 11 C++:
 12     #include<stack>
 13     stack<int> st;
 14     st.push(11);
 15     st.push(22);
 16     int x;
 17     st.top();//返回是返回的一个引用 避免拷贝用内存过多 
 18     st.pop();//只弹栈
 19     st.empty();
 20     */
 21 
 22 //顺序栈 
 23 struct Stack{
 24     int *data;//动态分配内存 不固定大小 int data[100](固定) 
 25     int capacity;
 26     int top;
 27 };
 28 
 29 void init(struct Stack *ps, int capacity){
 30     //指向一个栈的指针 容量
 31     
 32     ps->capacity = capacity;
 33     //总大小 = int * capacity 没毛病 
 34     ps->data = malloc(sizeof(int) * capacity);
 35     ps->top = 0;
 36     //-1 和 0都可以 指向最高元素或者最高元素再往上的空位置 
 37     //但是-1和0会导致后面的操作会有所不同 注意
 38      
 39 }
 40 
 41 //因为多个函数要用到判断栈满 所以写为一个函数 
 42 bool isFull(const struct Stack *ps){
 43     return ps->top == ps->capacity;//因为top = 0 
 44 }
 45 
 46 bool push(struct Stack * ps, int data){
 47     //异常判断 栈满 
 48     if(isFull(ps)) return false;
 49     else{
 50         //因为top = 0 
 51         ps->data[ps->top] = data;
 52         //注意 这里能看出 栈顶在top - 1的位置 
 53         top ++;
 54         return true;
 55     } 
 56 }
 57 
 58 //栈空时候不成功
 59 //为什么非得写一个函数?
 60 //我们写一个程序,里面的东西是作为接口提供给别人调用的 
 61 //别人只需要调用这个函数就行 内部细节不用给别人展现 
 62 bool isEmpty(const struct Stack *ps){
 63     return ps->top == 0;
 64 } 
 65 
 66 bool pop(struct Stack *ps, int *px){
 67     //栈空 
 68     if(isEmpty(ps)) return false;
 69     else{
 70         //top = 0; 栈顶元素在top-1的位置 
 71         ps->top --;
 72         *px  = ps->data[ps->top];
 73         return true;
 74     }
 75 }
 76 //查看栈顶元素 
 77 int top(const struct Stack *ps, int *px){
 78     //栈空 
 79     if(isEmpty(ps)) return 0;
 80     else{
 81         //top = 0; 栈顶元素在top-1的位置 
 82 
 83         *px  = ps->data[ps->top - 1];
 84         //*px是x的内容,已经把栈顶元素数据赋值给main中的x了,return只是表明是否获取成功 
 85         return 1;
 86     }
 87 }
 88 
 89 void destroy(struct Stack *ps){
 90     //只有data是malloc的 
 91     free(ps->data);
 92 }
 93 
 94 /***写函数 先写调用 再根据调用写具体内容***/
 95 int main(){
 96     struct Stack st;
 97     //初始化
 98     init(&st, 5);//要改变内容 所以要传地址; 多大    
 99     //压栈 
100     push(&st, 11);//栈;元素数据 
101     //弹栈 有两种,一种只负责弹出栈顶元素;另一种除了弹出还要返回弹出的值 
102     //top()这个去查看栈顶元素 
103     int x;//获取弹出值 
104     pop(&st, &x);
105     top(&st, &x);
106     destroy(&st);
107     /***记得free!!!防止内存泄露 但是main中写也有问题 这样就是把细节展现在外面了***/
108     return 0;
109 }
110 
111 **实例**后缀式求值
112 科普运算:运算符在运算数的位置中 后 前
113     中缀式:3+5*2
114     后缀式(逆波兰式) 352*+
115     前缀式(波兰式) +3*52
116 
117 后缀式求值的思路:看见一个运算数,没有办法,先放一下,最终看见了运算符,可以做运算了
118                 运算的运算数哪里来,就是前面的两个数.
119 例如:3 5 2 1 - * +,读 3 5 2 1 都没有处理方法,先晾着,然后读到了-,我们就可以做运算了,
120 那么要做运算的话,我们就需要运算数,运算数从哪里来啊,又因为是一个二元运算符,就前面拿来两个运算数,
121 这个操作就有点像栈,栈先存下了数字,到了运算符,就弹出.
122 
123 题目:根据后缀式求值
124 输入样例:3 5.4 2.2 * +
125 输出样例:14.9
126 
127 py实现代码
128 
129 //函数计算
130 def cal(x, y, op):
131     if op == '+':
132         return x + y
133     else if op == '-'
134         return x - y
135     else if op == '*'
136         return x * y
137     else if op == '/'
138         return x / y
139 
140 exp = input().split() //输入表达式并把每个字符分割 如3 5.5 + 2 / 会分割为一个列表['3' '5.5' '+' '2' '/']
141 st = list() //创建栈
142 for i in exp:
143     if i in '+-*/'://碰到运算符就退出
144         b = st.pop()
145         a = st.pop()
146         st.append(cal(a, b, i))
147     else://不是运算符就压栈
148         st.append(float(i))
149 
150 print('%.lf' % st.pop())

 

posted @ 2021-07-31 22:04  WriteOnce_layForever  阅读(56)  评论(0编辑  收藏  举报