1、栈
1.1 栈的顺序存储结构
#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--
1.2 栈的链式存储结构
#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;
}
43210
3210
0123请按任意键继续. . .
1.3 两栈共享空间
1.4 栈的应用之 逆波兰表示法
数字表达式转化成逆波兰表达式:
遇到数字直接输出,遇到符号入栈,遇到右括号时出栈,遇到符号时,比较和栈顶元素,若优先级比栈顶元素低或者相同,则栈内元素依次出栈,同时将该符号入栈。
如(+比*低,比-相同,所以*-出栈,+入栈)。
9+(3-1)*3+10/2 为 931-3*+10 2/+
逆波兰表达式的运算:
遇到数字入栈,遇到符号,将栈顶元素进行运算,将结果入栈,依次类推
2、队列
2.1 队列的顺序存储结构
#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
2.2 队列的链式存储结构
#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进行操作。