栈
来源:互联网 发布:淘宝返利网怎么用视频 编辑:程序博客网 时间:2024/05/20 19:50
栈
栈是限定仅在表未进行插入和删除操作的线性表,允许插入和删除的一端称为栈顶,另一端称为栈底,不包含任何元素的栈称为空栈。栈的储存方式有两种,一种是链式存储,一种是顺序存储。下面给出顺序存储的代码和解析:
顺序栈
warehouse.h文件下
#pragma once#define Maxsize 50class Stack{private: int StackList[Maxsize];//声明数组存取栈元素 int top;//记录栈顶public: Stack(); ~Stack() {} bool IsEmpty();//判断栈空 bool IsFull();//判断栈满 int GetTop();//取栈顶元素 void Push(int x);//压栈 int Pop();//出栈 void Clear();//清空栈};
warehouse.cpp文件
#include<iostream>#include"warehouse.h"using namespace std;Stack::Stack(){ top = -1;//构造函数定义栈空时栈顶为-1(数组由下标由0开始,故空时定义为-1)}bool Stack::IsEmpty(){ if (top == -1) return true; else return false;}bool Stack::IsFull(){ if (top == Maxsize - 1) return true; else return false;}int Stack::GetTop(){ if (IsEmpty()) { cout << "栈空" << endl; exit(0); } else return StackList[top];}void Stack::Push(int x){ if (IsFull()) { cout << "栈满" << endl; exit(0); } else { StackList[++top] = x; }}int Stack::Pop(){ if (IsEmpty()) { cout << "栈空!!" << endl; exit(0); } else { return StackList[top--]; }}void Stack::Clear(){ top = -1;}
main.cpp文件
#include<iostream>#include"warehouse.h"using namespace std;int main(){ Stack s; int x; cin >> x; s.Push(x); return 0;}//顺序栈即对top栈顶值进行操作----数组;
顺序栈相对比较简单容易理解,基本是对数组的一些操作。
链栈
在这里我分了两个文件:
(在vs2015环境下对template类型分文件不兼容故合并了warehouse.h文件和warehouse.cpp文件)
1.warehouse.h文件:
#pragma once#include<iostream>#include<string>using namespace std;template<class Type>struct StackNode{ Type data;//声明Type类型 StackNode<Type> *next;//声明结构体StackNode指针next用来指向下一个结构体类型};template<class Type>class Stack{public: Stack(){top = new StackNode<Type>;top->next = NULL;};//这里栈顶并不存储data。初始化为空栈 ~Stack(){Clear();delete top;};//析构调用Clear函数清空,并删除top栈顶 void Creation();//建栈 void Ergodic();//遍历 void Push(Type);//入栈 Type Pop();//出栈 Type GetTop();//取栈顶 bool IsEmpty();//判断栈空 void Clear();//清空private: StackNode<Type> *top;//对结构体类型组合声明top栈顶};/*拓展函数部分,可以忽略*/void Transform(int n,int d);//10进制转换函数void ChangEexpression(char *s1, char *s2);int Precedence(char op);char* StrChangeChar(string s1);double Count(char *s1);/*-------------------定义部分-----------------*/template<class Type>void Stack<Type>::Creation(){ StackNode<Type> *p; int i; int n; //cout << "输入栈元素个数:"; cin >> n; //cout << "输入元素:"; for (i = 0; i < n; i++) { p = new StackNode<Type>;//为p申请内存空间 cin >> p->data; p->next = top->next;//新元素next指针指向栈顶元素 top->next = p;//将每个新的p放在top后使新元素变为栈顶 }}template<class Type>void Stack<Type>::Ergodic()//遍历操作{ StackNode<Type> *p; p = top->next; while (p)//从栈顶开始遍历当到栈底即p=NUll时结束循环 { cout << p->data << " "; p = p->next; } cout << endl;}template<class Type>void Stack<Type>::Push(Type x)//入栈{ StackNode<Type> *p; p = new StackNode<Type>; p->data = x; p->next = top->next;//与建栈的思路一样 top->next = p;}template<class Type>Type Stack<Type>::Pop()//出栈{ if (IsEmpty()) { cout << "出栈时栈空" << endl; exit(0); } Type r;//记录出栈元素data的值 StackNode<Type> *p; p = top->next;//取栈顶 r = p->data;//记录值 top->next = p->next;//使标记的next指针指向栈顶的下一个 delete p;//删除 return r;//返回删除的栈顶的元素值(在栈的应用中此值会很有用)}template<class Type>Type Stack<Type>::GetTop()//取栈顶不涉及删除操作,只需返回栈顶元素的data值{ if (IsEmpty()) { cout << "取栈顶时栈空" << endl; exit(0); } StackNode<Type> *p; p = top->next; return p->data;}template<class Type>bool Stack<Type>::IsEmpty(){ if (top->next == NULL) return true; else return false;}template<class Type>void Stack<Type>::Clear(){ StackNode<Type> *p; p = top->next; while (p) { top->next = p->next;//可以看作是对出栈的循环调用直到栈空 delete p; p = top->next; }}//template<class Type>进制转换void Transform(int N, int d){ Stack<int> s; int k; while (N != 0) { k = N%d; s.Push(k); N = N / d; } s.Ergodic();}/*下面是对栈的实际应用,表达式求值*///template<class Type>//中缀表达式转换后缀表达式 (a+b)*c+d a b + c * d +void ChangEexpression(char * s1, char * s2){ Stack<char> s;//将运算符压入栈中 s.Push('#'); int i = 0, j = 0; char ch = s1[i]; while (ch!='\0') { if (ch == ' ') ch = s1[++i]; else if (ch=='(') { s.Push(ch); ch= s1[++i]; } else if (ch==')') { while (s.GetTop()!='(') { s2[j++] = s.Pop(); } s.Pop(); ch = s1[++i]; } else if(ch=='+'||ch=='-'||ch=='*'||ch=='/') { char m = s.GetTop(); while (Precedence(m)>=Precedence(ch)) { s2[j++] = s.Pop(); m = s.GetTop(); } s.Push(ch); ch = s1[++i]; } //遇到数字直接写入 else { if ((ch<'0' || ch>'9') && ch != '.') { cout << "中缀表达式错误" << endl; exit(0); } while (ch>='0'&&ch<='9'||ch=='.') { s2[j++] = ch; ch = s1[++i]; } s2[j++] = ' '; } } ch = s.Pop(); while (ch!='#') { if (ch == '(') { cout << "表达式错误" << endl; exit(0); } else { s2[j++] = ch; ch = s.Pop(); } } s2[j++] = '\0';}//中缀表达式转换后缀表达式 (a+b)*c+d a b + c * d + //符号优先级inline int Precedence(char op){ switch (op) { case'+': case'-': return 1; case'*': case'/': return 2; case'(': case'#': default: return 0; } return 0;}//char类型转换string类型;inline char * StrChangeChar(string s1){ int n = s1.length(); char *s11 = new char[n]; int i; for (i = 0; i < n; i++) { s11[i] = s1[i]; } s11[i] = '\0'; return s11;}//后缀表达式求值inline double Count(char * s1){ Stack<double> s; int i=0; double x, y; while (s1[i]) { while(s1[i] == ' ') { i++; continue; } switch (s1[i]) { case'+': x = s.Pop() + s.Pop(); s.Push(x); i++; break; case'-': x = s.Pop(); x = s.Pop() - x; s.Push(x); i++; break; case'*': x = s.Pop() * s.Pop(); s.Push(x); i++; break; case'/': x = s.Pop(); if (x == 0) { cout << "分母不能为0" << endl; exit(0); } x = s.Pop() / x; s.Push(x); i++; break; default: x = 0; while(s1[i] >= 48 && s1[i] <= 57) { x = x * 10 + s1[i] - 48; i++; } if (s1[i] == '.') { i++; y = 0; double j = 10.0; while (s1[i] >= 48 && s1[i] <= 57) { y = y + (s1[i] - 48) / j; i++; j = j * 10; } x = x + y; } s.Push(x); } } return s.GetTop();}//typora
2.main.cpp文件
#include<iostream>#include<string>#include"warehouse.h"using namespace std;int main(){ Stack<int> s; s.Creation(); cout<<s.GetTop()<<endl; cout << s.Pop() << endl; cout << s.GetTop() << endl; return 0;}
运行效果:
0 0