#include "stdafx.h" #include<iostream> #include<string.h> using namespace std; struct Sqstack { int *data; int top; int maxsize; Sqstack():top(-1){} //初始化为-1 }; void Push(Sqstack &S,int e) { if(S.top == S.maxsize-1)//把==写成了=,切忌以后不要再犯这样的错误 { cout<<"out of range push"<<endl; return; } S.data[++S.top]=e; } void Pop(Sqstack &S) { if(S.top==-1) { cout<<"out of range pop"<<endl; return; } S.top--; } int _tmain(int argc, _TCHAR* argv[]) { Sqstack S; cout<<"请输入栈的最大存储个数"<<endl; cin>>S.maxsize; S.data=new int[S.maxsize](); Push(S,1); cout<<S.data[S.top]<<endl; Pop(S); cout<<S.top<<endl; delete S.data; return 0; }
输出:
请输入栈的最大存储个数
10
1
-1
Press any key to continue
思想:
(1)对于这种顺序存储结构的,要想动态化其大小,我的做法是在成员中添加maxsize,然后动态化其大小,初始化top为-1
(2)对于push操作,注意不要满,注意==不要粗心写成=,否则会让你蛋疼
(3)对于pop操作,注意不要空,注意top--
#include "stdafx.h" #include<iostream> #include<string.h> using namespace std; struct Node { int data; Node *next; Node():next(NULL){} }; struct LinkStack { Node* top;//指向栈顶 int count; }; void Push(LinkStack* &S,int e) { Node *p=new Node(); p->data=e; p->next=S->top; //这里要尤其注意,因为S->就是个指针,始终指向当前,而不用p->next=S->top->next S->top=p; S->count++; } void Pop(LinkStack *S) { Node *p=S->top; S->top=p->next; delete p; } void PrintStack(LinkStack *S) { Node *p=S->top; while(p)//从本身开始,这个和链表的插入地方不一样,不是p->next { cout<<p->data; p=p->next; } } void Delete(Node *p) { if(p->next)Delete(p->next); cout<<p->data; delete p; } void DeleteStack(LinkStack *S) { Delete(S->top); } int _tmain(int argc, _TCHAR* argv[]) { LinkStack *S=new LinkStack(); for(int i=0;i<5;i++) { int a; cin>>a; Push(S,a); } PrintStack(S); cout<<'\n'; Pop(S); PrintStack(S); cout<<'\n'; DeleteStack(S); return 0; }
数字表达式转化成逆波兰表达式:
遇到数字直接输出,遇到符号入栈,遇到右括号时出栈,遇到符号时,比较和栈顶元素,若优先级比栈顶元素低或者相同,则栈内元素依次出栈,同时将该符号入栈。
如(+比*低,比-相同,所以*-出栈,+入栈)。
9+(3-1)*3+10/2 为 931-3*+10 2/+
逆波兰表达式的运算:
遇到数字入栈,遇到符号,将栈顶元素进行运算,将结果入栈,依次类推
#include "stdafx.h" #include<iostream> #include<string.h> #include<queue> using namespace std; struct Squeue { int *data; int maxsize; int front; int rear; Squeue():front(0),rear(0){} }; void EnQueue(Squeue &Q,int e) { if((Q.rear+1)%Q.maxsize==Q.front)//队列已满,实际定义为当还有一个元素的时候定义队列满 { cout<<"out of range"<<endl; return; } Q.data[Q.rear]=e; Q.rear=(Q.rear++)%Q.maxsize; } void DeQueue(Squeue &Q,int &e) { if(Q.front==Q.rear) { cout<<"Queue is empty"<<endl; return; } e=Q.data[Q.front]; Q.front=(Q.front++)%Q.maxsize; } int QueueLength(Squeue &Q) { return (Q.rear-Q.front+Q.maxsize)%Q.maxsize; } int _tmain(int argc, _TCHAR* argv[]) { Squeue Q; cout<<"请输入队列长度"<<endl; cin>>Q.maxsize; Q.data=new int[Q.maxsize](); for(int i=0;i<3;i++) EnQueue(Q,i); cout<<QueueLength(Q)<<'\n'; int e; DeQueue(Q,e); cout<<e; return 0; }
输出:
请输入队列长度
4
3
0请按任意键继续. . .
思想:
(1)队列在初始状态下为rear=0 front=0 也就是说队列空位 front = rear
(2)这里标记当还有一个空的时候为队列满(否则无法区分是队列空还是队列满了)即(rear+1)%maxsize=front
(3)队列的长度为 (rear-front+maxsize)%maxsize
(4)rear或者front前移的时候为 (rear+1)%maxsize
#include "stdafx.h" #include<iostream> #include<string.h> #include<queue> using namespace std; struct Node { int data; Node *next; }; struct LinkQueue { Node *front; Node *rear; }; void EnQueue(LinkQueue &Q,int e) { Node *p=new Node();//只能在队尾插入,让队列更长,rear始终指向队尾 p->data=e; Q.rear->next=p; Q.rear=p; } void DeQueue(LinkQueue &Q,int &e) { if(!Q.front->next) { cout<<"queue is empty"; return; } Node *p=Q.front->next; Q.front->next=p->next; if(p==Q.rear)//当只有一个元素的时候,让rear也指向头指针,不然最后一个元素删掉,rear就不知道指哪了 Q.rear=Q.front; e=p->data; delete p; } int _tmain(int argc, _TCHAR* argv[]) { LinkQueue Q; Q.front=new Node(); Q.rear=Q.front;//指向同一头节点 EnQueue(Q,1); EnQueue(Q,2); int e; DeQueue(Q,e); cout<<e; DeQueue(Q,e); cout<<e; DeQueue(Q,e); cout<<e; return 0; }
输出:
12queue is empty2请按任意键继续. . .
思想:
(1)队列结构为 front 和rear节点组成
(2)队列建立的时候要先建立头节点,并将front和rear指向头节点
(3)入队操作:只能在队尾操作,也就是用尾插法,只对rear进行修改,队伍不断从后面加长,rear始终在最后
(4)出队操作:删除头节点后面的元素,当只有一个元素的时候,要将rear 也指向头节点,也就是说主要对front进行操作。