一、栈
逻辑结构:同线性表-一对一
存储结构:顺序栈和链栈均可,顺序栈常见
只能栈顶运算,先入后出原则
//SElemType 可替换为int等数据类型
//1.构造顺序栈
struct SqStack
{
SElemType *top;
SElemType *base;
int stacksize;
};
//2.顺序栈的初始化
Status InitStack(SqStack &s)
{
s.base=new SElemType [MAXSIZE];
if(!s.base)
exit(OVERFLOW);
s.top=s.base;
s.stacksize=MAXSIZE;
return Ok;
}
//3.判断顺序栈是否为空
bool StackEmpty(SqStack s)
{
if(s.top==s.base)
return true;
else
return false;
}
//4.清空
void ClearStack(SqStack &s)
{
if(s.base)
s.top=s.base;
}
//5.销毁
void DestroyStack(SqStack &s)
{
if(s.base)
{
delete s.base;
s.stacksize=0;
s.base=s.top=NULL;
}
}
//6.顺序栈进栈
void Push(SqStack &s,SElemType e)
{
if(s.top-s.base!=s.stacksize)//top-base不能栈满
{
*s.top=e;
s.top++;
//*s.top++=e;
}
}
//7.顺序栈出栈
void Pop(SqStack &s,SElemType &e)
{
if(s.top!=s.base) //不能栈空
{
--s.top;
e=*s.top;
//e=*--s.top;
}
}
//8.取顺序栈栈顶元素
void GetTop(SqStack s,SElemType &e)
{
if(s.base!=s.top)
e=*(s.top-1);
}
2.链栈
#include <iostream>
using namespace std;
#define MAXSIZE 100
//1.构造链栈
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
//2.初始化链栈 s->^ 即可
void InitLinkStack(LinkStack &s)
{
s=NULL;
}
//3.判断链栈是否为空
bool IsEmptyLStack(LinkStack s)
{
if(s==NULL)
return true;
else
return false;
}
//4.进栈,将p放在首位
void PushLStack(LinkStack &s,ElemType e)
{
LinkStack p;
p=new StackNode;
if(!p)
exit(OVERFLOW);//溢出用exit()函数
p->data=e;
p->next=s;
s=p;
}
//5.出栈
void PopLStack(LinkStack &s,ElemType &e)
{
if(s)//要保证s不为空
{
e=s->data;
LinkStack p;
p=s;
s=s->next;
delete p;
}
}
//6.取栈顶元素
SElemType GetTop(LinkStack s)
{
if(s==NULL)
exit(1);
return s->data;
}
二、栈的应用
1.数制转换(十进制转N进制)用栈暂存低位值
#include <iostream>
using namespace std;
#define num 8//表示转化为8进制
void conversion()
{
int n;
InitStack(s);
cin>>n;
while(n)
{
push(s,n%num);
n=n/num;
}
while(!stackEmpty(s))//栈非空时弹出
{
pop(s,e);
cout<<e;
}
}
2.括号匹配的检验(用栈暂存左括号)
可运行-转载
#include <iostream>
#include <string>
using namespace std;
#define maxsize 100
struct sStack
{
char sign[maxsize];
int top;
};
int InitsStack(sStack &SS)
{
SS.top=-1;
return 1;
}
int IsEmptysStack(sStack &SS)
{
if(SS.top==-1)
return 1;
return 0;
}
int PushsStack(sStack &SS,char c)
{
SS.sign[++SS.top]=c;
return 1;
}
int UpsStack(sStack &SS)
{
if(IsEmptysStack(SS))
{
cout<<"栈空"<<endl;
return 0;
}
SS.top--;
return 1;
}
char TopsStack(sStack &SS)
{
if(IsEmptysStack (SS))
{
cout <<"栈空"<<endl;
return 0;
}
return SS.sign[SS.top];
}
int main()
{
string s;
cout<<"输入表达式:";
cin>>s;
int length=s.length();
int i;
sStack SS;
InitsStack(SS);
for(i=0;i<length;++i)
{
if(s[i]=='('||s[i]=='['||s[i]=='{')
PushsStack(SS,s[i]);
else if(s[i]==')'&&!IsEmptysStack(SS)&&TopsStack(SS)=='(')
UpsStack(SS);
else if(s[i]==')'&&!IsEmptysStack(SS)&&TopsStack(SS)!='(')
cout<<"括号匹配次序不正确"<<endl;
else if(s[i]==']'&&!IsEmptysStack(SS)&&TopsStack(SS)=='[')
UpsStack(SS);
else if(s[i]==']'&&!IsEmptysStack(SS)&&TopsStack(SS)!='[')
cout<<"括号匹配次序不正确"<<endl;
else if(s[i]=='}'&&!IsEmptysStack(SS)&&TopsStack(SS)=='{')
UpsStack(SS);
else if(s[i]=='}'&&!IsEmptysStack(SS)&&TopsStack(SS)!='{')
cout<<"括号匹配次序不正确"<<endl;
else if((s[i]==')'||s[i]==']'||s[i]=='}')&&IsEmptysStack(SS))
cout<<"右括号多于左括号"<<endl;
}
if(!IsEmptysStack(SS))
cout<<"左括号多于右括号"<<endl;
else if(i=(length-1)&&IsEmptysStack(SS))
cout<<"括号匹配正确"<<endl;
system("PAUSE");
return 0;
}
3.表达式求值(用栈暂存运算符)
算法思想如下:#include <iostream>
#include <stack>
using namespace std;
void main()
{
stack<char> s;
char c,x;
int flag=1;
cin>>c;
while(c!='#'&&flag)
{
switch(c)
{
case '['||'(':
s.push(c);
break;
case ')':
x=s.top();
if(x=='(')
s.pop();
else
flag=0;
break;
case ']':
x=s.top();
if(x=='[')
s.pop();
else
flag=0;
break;
}
cin>>c;
}
}
转载:任意表达式求值-方法
http://blog.csdn.net/flyfy1/article/details/5309551
4.迷宫求解(用栈实现递归调用)
“分治法”求解递归问题
void p(参数)
{
If(递归结束条件成立)
可直接求解;
elsep(较小或较大的参数);//递归步骤
}
递归解决的问题:
1) n阶乘
fact(n)={1若n=0; n*fact(n-1);若n>0}
2) 斐波那契
Fib(n)={1 若n=1,2; fib(n-1)+fib(n-2) 其他}
3) 汉诺塔
把n-1个盘子从A移到B,把最下面的移到C;
把n-2个盘子从B移到A,第n-1个移到C,如此反复
4) 迷宫
5) 转二进制
void conversion(int n)
{
if(n==1)
cout<<n%2;
else
{
conversion(n/2);
cout<<n%2;
}
}
递归适用树,广义表
时间效率O(2^n),与递归树的结点数成正比
空间效率O(n),与递归树的深度成正比
三、队列
先进先出
顺序表示-一维数组
1.循环队列
#include <iostream>
using namespace std;
#define MAXQSIZE 100//最大队列长度
//1.构造循环队列
struct SqQueue
{
QElemType *base;
int front;//头指针,指向对头元素
int rear;//尾指针,指向队尾元素的下一个位置
};
//2.初始化
void InitQueue(SqQueue &q)
{
q.base=new QElemType[MAXQSIZE];
if(!q.base)
exit(OVERFLOW);
q.front=q.rear=0;
}
//3.求循环对列长度
int QueueLength(SqQueue q)
{
return (q.rear-q.front+MAXQSIZE)%MAXQSIZE;
}
//4.入队列
void EnQueue(SqQueue &q,QElemType e)
{
if((q.rear+1)%MAXQSIZE!=q.front)
{
q.base[q.rear]=e;
q.rear=(q.rear+1)%MAXQSIZE;
}
}
//5.出队列
void DeQueue(SqQueue &q,QElemType e)
{
if(q.front!=q.rear)
{
e=q.base[q.front];
q.front=(q.front+1)%MAXQSIZE;
}
}
2.链队列
#include <iostream>
using namespace std;
//1.构造链队列
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front;//队头指针
QueuePtr rear;//对尾指针
}LinkQueue;
//2.初始化
void InitQueue(LinkQueue &q)
{
q.front=q.rear=(QueuePtr)malloc(sizeof(QNode));//malloc动态分配(大小)的内存
if(!q.front)
exit(OVERFLOW);
q.front-next=NULL;
}
//3.销毁队列
void DestroyQueue(LinkQueue &q)
{
while(q.front)
{
q.rear=q.front->next;
free(q.front);
q.front=q.rear;
}
}
//4,判断是否为空
bool EmptyQueue(LinkQueue q)
{
if(q.front==q.rear)
return true;
else
return false;
}
//5.求链队列的头元素
void GetHead(LinkQueue q,QElemType &e)
{
if(q.front!=q.rear)
e=q.front->next->data;
}
//6.链队列入队
void EnQueue(LinkQueue &q,QElemType e)
{
LinkQueue p;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(OVERFLOW);
p->data=e;
p->next=NULL;
q.rear->next=p;
q.rear=p;//修改队尾指针
}
//7.链队列出队
void DeQueue(LinkQueue &q,QElemType &e)
{
LinkQueue p=(QueuePtr)malloc(sizeof(QNode));
if(q.front!=q.rear)
{
p=q.front->next;
e=p->data;
q.front->next=p->next;
if(q.rear==p)
q.rear=q.front;
delete p;
}
}
3.队列应用
汽车加油
打印机缓冲区