//----------栈的顺序存储表示---------------------
#define StackInitSize 100
#define StackIncrement 10
typedef struct {
SElemType *base;
SElemType *top;
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;
status InitStack(SqStack &S){
//构造一个空栈
S.base=(SElemType *)malloc(StackInitSize*(sizeof(SElemType)));
if(!S.base)
exit(OVERFLOW);
S.top=S.base;
S.stacksize=StackInitSize;
return ok;
}
status GetTop(SqStack S,SElemType &e){
//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top==S.base)
return error;
e=*(S.top-1);
retutn ok;
}
status Push(SqStack &S,SElemType e){
//插入e为新的栈顶元素
if(S.top-S.base>=S.stacksize){
S.base=(SElemType *)realloc(S.base,(S.stacksize+StackIncrement)*sizeof(SElemType));
if(!S.base)
exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=StackIncremet;
}
*S.top++=e; //*S.top=e;S.top++
rerurn ok;
}
status Pop(SqStack &S,SElemType &e){
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回ok;否则返回error
if(S.top==S.base)
return error;
e=*--S.top; //S.top--;e=*S.top;
return ok;
}
//算法3.1
void conversion(){
//对于输入的任意一个非负十进制数,打印输出与其等值的八进制数
InitStack(S);
scanf("%d",N);
while(N){
Push(S,N%8);
N=N/8;
}
while(!StackEmpty(S)){
Pop(S,e);
printf("%d",e);
}
}
//算法3.2
void LineEdit(){
//利用字符栈S,从终端接受一行并传送至调用过程的数据区
InitStack(S);
ch=getchar();
while(ch!=EOF){
while(ch!=EOF&&ch!='\n'){
switch(ch){
case '#':Pop(S,c);
break;
case '@':ClearStack(S);
break;
default:Push(S,ch);
break;
}
ch=getchar();
}
将从栈底到栈顶的栈内字符传送至调用过程的数据区;
ClearStack(S);
if(ch!=EOF)
ch=getchar();
}
DestroyStack(S);
}
//算法3.3迷宫求解
typedef struct {
int ord; //通道块在路径上的“序号”
PosType seat; //通道块在迷宫中的“坐标位置”
int di; //从此通道块走向下一通道块的“方向”
}SElemType; //栈的元素类型
status MazePath(MazeType maze,PosType start,PosType end){
//若迷宫maze中存在从入口strat到出口end的通道,则求得一条存放在栈中(从栈底到栈顶),并返回TRUE,否则返回FALSE
InitStack(S);
curpos=start; //设定“当前位置”为“入口位置”
curstep=1; //探索第一步
do{
if(pass(curpos)){ //当前位置可以通过,既是未曾走到过的通道块
FootPrint(curpos); //留下足迹
e=(curstep,curpos,1);
Push(S,e); //加入路径
if(curpos==end) //到达终点(出口)
return true;
curpos=NextPos(curpos,1); //下一位置是当前位置的东邻
curstep++; //探索下一步
}
else{ //当前位置不能通过
if(!StackEmpty(S)){
Pop(S,e);
while(e.di==4&&!StackEmpty(S)){
MarkPrint(e.seat); //留下不能通过的标记
Pop(S,e); //并退回一步
}
if(e.di<4){
e.di++;
Push(S,e); //换下一个方向探索
curpos=NextPos(e.seat,e.di);
}
}
}
}while(!StackEmpty(S));
return (FALSE);
}
//算法3.4
OperandType EvaluateExpression(){
//算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符的集合
InitStack(OPTR);
Push(OPTR,'#');
InitStack(OPND);
c=getchar();
while(c!='#'||GetTop(OPTR)!='#'){
if(!In(c,OP)) //不是运算符则进栈
{
Push(OPND,c);
c=getchar();
}
else
switch(Precede(GetTop(OPTR),c)){
case '<': //栈顶元素优先权低
Push(OPTR,c);
c=getchar();
break;
case '=': //脱括号并接收下一个字符
Pop(OPTR,x);
c=getchar();
break;
case '>': //退栈并将运算结果入栈
Pop(OPTR,theta);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
}
}
return GetTop(OPND);
}
//算法3.5
void hanoi(int n,char x,char y,char z){
//将塔座x上按直径由小到大且自上而下编号为1至n的n个圆盘按规则搬到塔座z上,y可用作辅助塔座
//搬动操作move(x,n,z)
if(n==1)
move(x,1,z);
else{
hanoi(n-1,x,z,y);
move(x,n,z); //将编号为n的圆盘从x移到z
hanoi(n-1,y,x,z);
}
}
//------------单链队列————————队列的链式存储结构--------------
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
status InitQueue(LinkQueue &Q){
//构造一个空队列Q
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)
exit(OVERFLOW);
Q.front->next=NULL;
return ok;
}
status DestroyQueue(LinkQueue &Q){
//销毁队列Q
while(Q.front){
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return ok;
}
status EnQueue(LinkQueue &Q,QElemType e){
//插入元素e为Q的新的队尾元素
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return ok;
}
status DeQueue(LinkQueue &Q,QElemType &e){
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK
//否则返回error
if(Q.front==Q.rear)
return error;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
return ok;
}
//----------------循环队列——————队列的顺序存储结构------------
#define MAXQSIZE 100 //最大队列长度
typedef struct {
QElemType *base; //初始化的动态分配存储空间
int front; //头指针,若队列不空,指向队列头元素
Int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;
status InitQueue(SqQueue &Q){
//构造一个空队列Q
Q.base=(QElemType *)malloc(MAXSIZE*sizeof(QElemType));
if(!Q.base)
exit(OVERFLOW);
Q.front=Q.rear=0;
return ok;
}
int QueueLength(SqQueue Q){
//返回Q的元素个数,即队列的长度
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}
status EnQueue(SqQueue &Q,QElemType e){
//插入元素e为Q的新的队尾元素
if((Q.rear+1)%MAXSIZE==Q.front)
return error; //队列满*************
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
return ok;
}
status DeQueue(SqQueue &Q,QElemType &e){
//若队列不空,则删除Q的队头元素,用e返回其值,并返回ok;否则返回error
if(Q.front==Q.rear)
return error; //判队空*************
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXSIZE;
return ok;
}
//算法3.6
void Bank_Sumulation(int CloseTime){
//银行业务模拟,统计一天内客户在银行逗留的平均时间
OpenForDay(); //初始化
while(MoreEvent){
EventDrived(OccurTime,EventType); //事件驱动
switch(EventType){
case 'A':CustomerArrived(); break; //处理客户到达事件
case 'D':CustomerDeparture(); break; //处理客户离开事件
default :Invalid();
}
}
CloseForDay();
}
//算法3.7-----------模拟程序-------------------
typedef struct {
int OccurTime; //事件发生时刻
int NType; //事件类型,0表示到达事件,1至4表示四个窗口的离开事件
}Event,ElemType;
typedef LinkList EventList; //事件链表类型,定义为有序链表
typedef struct {
int ArrivalTime; //到达时刻
int Duration; //办理业务所需时间
}QElemType; //队列的数据元素类型
//----------程序中用到的主要变量
EventList ev; //事件表
Event en; //事件
LinkQueue q[5]; //四个客户队列
QElemType customer; //客户记录
Int TotalTime,CustomerNum; //累计客户逗留事件,客户数
int cmp(Event a,Event b);
//依据事件a的发生时刻<或=或>事件b的发生时刻分别返回-1或0或1
void OpenForDay(){
//初始化操作
TatalTime=0; CustomerNum=0; //初始化累计时间和客户数为0
InitList(ev); //初始化事件链表为空表
en.OccurTime=0; en.NType=0; //设定第一个客户到达事件
OrderInsert(ev,en.cmp); //插入事件表
for(i=1;i<=4;++i)
InitQueue(q[i]); //置空队列
}
void CustomerArrived(){
//处理客户到达事件,en.NType=0;
++CustomerNum;
Random(durtime,intertime); //生成随机数
t=en.OccurTime+intertime; //下一客户到达时刻
if(t<CloseTime) //银行尚未关门,插入时间表
OrderInsert(ev,(t,0).cmp);
i=Minimum(q); //求长度最短队列
EnQueue(q[i],(en.OccurTime,durtime));
if(QueueLength(q[i])==1)
OrderInsert(ev,(en.OccurTime+durtime,i),cmp); //设定第i队列的一个离开事件并插入事件表
}
void CustomerDeparture(){
//处理客户离开事件,en.NType>0
i=en.NType;
DelQueue(q[i],customer); //删除第i队列的排头客户
TotalTime+=en.OccurTime-customer.ArrivalTime; //累计客户逗留时间
if(!QueueEmpty(q[i])){
//设定第i队列的一个离开事件并插入事件表
GetHead(q[i],customer);
OrderInsert(ev,(en,OccurTime+curtomer.Duration,i),(*cmp)());
}
}
void Bank_Simulation(int ClosrTime){
OpenForDay();
while(!ListEmpty(ev)){
DelFirst(GetHead(ev),p);
en=GetCurElem(p);
if(en.NType==0)
CustomerArrived();
else
CustomerDeparture();
}
printf("the average time is %f\n",(float)TotalTime/CustomerNum);
}
数据结构伪C代码:栈和队列
最新推荐文章于 2022-09-06 20:27:15 发布