数据结构之栈和队列应用
1.实验题目
设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。
2.需求分析
本演示程序用TC编写,完成单链表的生成,任意位置的插入、删除,以及确定某一元素在单链表中的位置。
① 输入的形式和输入值的范围:插入元素时需要输入插入的位置和元素的值;删除元素时输入删除元素的位置;查找操作时需要输入元素的值。在所有输入中,元素的值都是整数
② 输出的形式:在所有三种操作中都显示操作是否正确以及操作后单链表的内容。其中删除操作后显示删除的元素的值,查找操作后显示要查找元素的位置。
③ 程序所能达到的功能:完成单链表的生成(通过插入操作)、插入、删除、查找操作
④ 测试数据:
设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3, 20),(‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。其中,‘A’表示到达;‘D’表示离去,‘E’表示输入结束。
3.概要设计
1)为了实现上述程序功能,需要定义栈和队列的抽象数据类型:
ADT Stack{
数据对象:D={n|n∈ElemSet,0<n≤100}
数据关系:R={<n-1,n>|n,n-1∈D}
基本操作:
InitStack(CarStack *s,int maxsize)
操作结果:初始化栈
CreatStack(CarNode *Car,CarStack *garage)
初始条件:栈已存在
操作结果:将能停在停车场中的车辆信息输入栈
PopStack(CarStack *garage,CarStack *Temp,LinkQueue *road,InputData *inputdata)
初始条件:栈已存在
操作结果:获取栈中的车辆信息
InfoStack(CarStack *garage)
初始条件:栈已存在
操作结果:查询栈中信息并输出 }
ADT Queue{
数据对象:D={n|n∈ElemSet,0<n≤100}
数据关系:R={<n-1,n>|n,n-1∈D}
基本操作:
InitQueue(LinkQueue *road)
操作结果:初始化队列
CreatQueue(CarNode *Car,LinkQueue *road
初始条件:队列已存在
操作结果:将停在便道中的车辆信息输入队列
PopQueue(CarNode *Car,LinkQueue *road)
初始条件:队列已存在
操作结果:获取队列中的车辆信息
InfoQueue(LinkQueue *road)
初始条件:队列已存在
操作结果:查询队列中信息并输出 }
2)本程序包含12个函数:
①主函数main()
②初始化栈的InitStack()
③初始化队列InitQueue()
④记录进入停车场的车辆信息CreatStack()
⑤记录进入便道的车辆信息CreatQueue()
⑥记录开出停车场的车辆信息PopStack()
⑦记录开出便道的车辆信息PopQueue()
⑧获取车辆状态信息GetCarNode()
⑨查询停车场内车辆信息InfoStack()
⑩查询便道内车辆信息InfoQueue()
⑪打印输出出库车辆信息及停车费Print()
⑫用户输入数据Input()
4.详细设计
实现概要设计中定义的所有的数据类型,对每个操作给出伪码算法。对主程序和其他模块也都需要写出伪码算法。
1)栈的定义
1 typedef struct StackNode{ 2 3 int num; 4 5 Time arrive; 6 7 Time leave; 8 9 struct StackNode *next; 10 11 }CarNode; 12 13 typedef struct Stack{ 14 15 CarNode *stack[n]; 16 17 int top; 18 19 }CarStack;
2)栈的基本操作
1 void InitStack(CarStack *s,int maxsize){ 2 3 s->stack[s->top+i] = NULL; 4 5 s->stack[s->top+i] = (CarNode *)malloc(sizeof(CarNode));} 6 7 void CreatStack(CarNode *Car,CarStack *garage){ 8 9 garage->stack[garage->top]=Car; 10 11 garage->top++;} 12 13 void InfoStack(CarStack *garage){ 14 15 for(i=0;i<garage->top;i++) 16 17 输出停车场位置 车辆号码 到达时刻} 18 19 void Print(CarNode *Car) 20 21 { arr=Car->arrive; 22 23 lea=Car->leave; 24 25 输出车辆的号码 进库时刻 离开时刻 车费(元) 26 27 }
3)队列的定义
1 typedef struct Queue 2 3 {CarNode *head; 4 5 CarNode *rear; 6 7 }LinkQueue;
4)队列的基本操作
1 void InitQueue(LinkQueue *road) 2 3 {road->head=(CarNode *)malloc(sizeof(CarNode)); 4 5 if(road->head!=NULL) 6 7 {road->head->next=NULL; 8 9 road->rear=road->head; 10 11 } 12 13 } 14 15void CreatQueue(CarNode *Car,LinkQueue *road) 16 17 {CarNode *QueueCar; 18 19 QueueCar=Car; 20 21 QueueCar->next=NULL; 22 23 road->rear->next=QueueCar; 24 25 road->rear=QueueCar; 26 27 } 28 29 void InfoQueue(LinkQueue *road) 30 31 {CarNode *p; 32 33 p=road->head->next; 34 35 if(road->head==road->rear) 36 37 输出"便道里没有车!" 38 39 else 40 41 输出 便道位置 车辆号码;}
5)其他函数
1 void GetCarNode(CarStack *garage,LinkQueue *road,InputData *inputdata,int maxsize) 2 3 { CarNode *Car=(CarNode *)malloc(sizeof(CarNode)); 4 5 if(garage->top<maxsize&&garage->top>=0) 6 7 {CreatStack(Car,garage); 8 9 输出"车辆进入车库!"} 10 11 else 12 13 {CreatQueue(Car,road); 14 15 输出"车库已满,车辆停入便道";} 16 17 } 18 19 void Input(InputData *inputdata) 20 21 { 输出A(a)-入库 D(d)-离开 P(p)-查看停车场车辆 W(w)-查看过道车辆 E(e)-输入结束的提示; 22 23 case 'A': 24 25 case 'a':调用获取车辆信息函数GetCarNode() 26 27 case 'D': 28 29 case 'd':调用车出库函数PopStack() 30 31 case 'P': 32 33 case 'p':查询停车场的信息,调用函数InfoStack() 34 35 case 'W': 36 37 case 'w':查询便道车辆的信息,调用函数InfoQueue() 38 39 case 'E': 40 41 case 'e':输入结束 42 43 }
5.调试分析
malloc()是动态内存分配函数,用来向系统请求分配内存空间。当无法知道内存具体的位置时,想要绑定真正的内存空间,就要用到malloc()函数。因为malloc只管分配内存空间,并不能对分配的空间进行初始化,所以申请到的内存中的值是随机的,经常会使用memset()进行置0操作后再使用。与其配套的是free(),当申请到的空间不再使用时,要用free()函数将内存空间释放掉,这样可以提高资源利用率,最重要的是----就是因为它可以申请内存空间,然后根据需要进行释放,才被称为“动态内存分配”
6.使用说明
根据提示“请输入停车场容量Maxsize:”输入数据(即题目中n的值),回车输入结束,出现如下菜单:
*******************************************************************************************
欢迎光临停车场
本停车场按停留的时间长短交纳费用
请输入车库命令,格式为“出(入)库 车牌号 出(入)库时间”
A:到达 D:离去 P:查看停车场车辆 W:查看过道车辆 E:输入结束
*******************************************************************************************
按照此提示一次键入数据即可。
7.测试结果
8.附代码:

1 // 实验二.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 6 7 #include<iostream> 8 using namespace std; 9 #define cost 2 10 #define n 100 //(即实验题目中的n) 11 typedef int Time; 12 13 typedef struct InputData 14 { 15 char command; 16 int num; 17 Time t; 18 }InputData;//保存输入的数据 19 20 typedef struct StackNode 21 { 22 int num; 23 Time arrive; 24 Time leave; 25 struct StackNode *next; 26 }CarNode;//入库车辆信息--栈 27 28 typedef struct Stack 29 { 30 CarNode *stack[n]; 31 int top; 32 }CarStack;//暂时停放车库--栈 33 34 typedef struct Queue 35 { 36 CarNode *head; 37 CarNode *rear; 38 }LinkQueue;//便道---队列 39 40 void InitStack(CarStack *s,int maxsize);//初始化栈 41 void InitQueue(LinkQueue *road);//初始化队列 42 void CreatStack(CarNode *Car,CarStack *garage);//车进库 43 void CreatQueue(CarNode *Car,LinkQueue *road);//车进便道 44 void PopQueue(CarNode *Car,LinkQueue *road);//车出便道 45 void PopStack(CarStack *garage,CarStack *Temp,LinkQueue *road,InputData *inputdata);//车出库 46 void GetCarNode(CarStack *garage,LinkQueue *road,InputData *inputdata,int maxsize);//获取车辆信息 47 void InfoStack(CarStack *garage);//车库的车辆信息 48 void InfoQueue(LinkQueue *road);//便道的车辆信息 49 void Print(CarNode *Car);//打印出库的车的信息 50 void Input(InputData *inputdata);//用户输入命令 51 52 void main() 53 { 54 InputData inputdata; 55 Input(&inputdata); 56 system("pause"); 57 } 58 59 void InitStack(CarStack *s,int maxsize)//初始化栈 60 { 61 int i; 62 s->top=0; 63 for(i=0;i<=maxsize-1;i++) 64 { 65 s->stack[s->top+i] = NULL; 66 s->stack[s->top+i] = (CarNode *)malloc(sizeof(CarNode)); 67 } 68 } 69 70 void InitQueue(LinkQueue *road)//初始化队列 71 { 72 road->head=(CarNode *)malloc(sizeof(CarNode)); 73 // road->rear=(CarNode *)malloc(sizeof(CarNode)); 74 if (!road->head) 75 { 76 cout<<"内存分配失败!"<<endl; 77 exit(0); 78 } 79 if(road->head!=NULL) 80 { 81 road->head->next=NULL; 82 road->rear=road->head; 83 } 84 } 85 86 void GetCarNode(CarStack *garage,LinkQueue *road,InputData *inputdata,int maxsize)//获取车辆信息 87 { 88 CarNode *Car=(CarNode *)malloc(sizeof(CarNode)); 89 if (!Car) 90 { 91 cout<<"内存分配失败!"<<endl; 92 exit(0); 93 } 94 Car->num = inputdata->num; 95 Car->arrive = inputdata->t; 96 if(garage->top<maxsize&&garage->top>=0) 97 { 98 CreatStack(Car,garage);//车进库 99 cout<<"车辆进入车库!"<<endl; 100 } 101 else 102 { 103 CreatQueue(Car,road);//车进便道 104 cout<<"车库已满,车辆停入便道"<<endl; 105 } 106 } 107 108 void CreatStack(CarNode *Car,CarStack *garage)//车进库 109 { 110 garage->stack[garage->top]=Car; 111 garage->top++; 112 } 113 114 void CreatQueue(CarNode *Car,LinkQueue *road)//车进便道 115 { 116 CarNode *QueueCar; 117 QueueCar=Car; 118 QueueCar->next=NULL; 119 road->rear->next=QueueCar; 120 road->rear=QueueCar; 121 } 122 123 void PopStack(CarStack *garage,CarStack *Temp,LinkQueue *road,InputData *inputdata)//车出库 124 { 125 CarNode *Car=(CarNode *)malloc(sizeof(CarNode)); 126 if (!Car) 127 { 128 cout<<"内存分配失败!"<<endl; 129 exit(0); 130 } 131 Car->num = inputdata->num; 132 Car->leave = inputdata->t; 133 int i = garage->top; 134 while (i) 135 { 136 if (garage->stack[i-1]->num != Car->num) 137 { 138 garage->top--;//进临时车站 139 Temp->stack[Temp->top]=garage->stack[garage->top]; 140 Temp->top++; 141 142 i--;//没有找到,继续循环查找 143 if (i==0) 144 { 145 cout<<"没有该车牌的车!"<<endl; 146 } 147 } 148 else//获得车辆信息,并回归临时车栈的车辆 149 { 150 Car->arrive = garage->stack[i-1]->arrive; 151 Print(Car);//打印车辆收费单 152 garage->top--; 153 while(Temp->top>0)//回归临时车站的车辆 154 { 155 Temp->top--; 156 garage->stack[garage->top]=Temp->stack[Temp->top]; 157 garage->top++; 158 } 159 if(road->head!=road->rear)//从便道出来一辆车到停车场 160 { 161 garage->stack[garage->top]=road->head->next; 162 cout<<endl; 163 cout<<"车场有空位,便道第一辆车可以进入!"<<endl; 164 garage->top++; 165 road->head=road->head->next; 166 } 167 i = 0;//已经找到,退出循环 168 } 169 } 170 } 171 172 void InfoStack(CarStack *garage)//查询车库车辆信息 173 { 174 if(garage->top==0) 175 cout<<"车库里没有车!"<<endl; 176 else 177 { 178 cout<<"(停车场位置 车辆号码 到达时刻)"<<endl; 179 for(int i=0;i<garage->top;i++) 180 { 181 cout<<"( "<<i+1<<" "<<garage->stack[i]->num<<" "<<garage->stack[i]->arrive<<" )"<<endl; 182 } 183 } 184 } 185 186 void InfoQueue(LinkQueue *road)//查询便道车辆信息 187 { 188 CarNode *p; 189 p=road->head->next; 190 int i=0; 191 if(road->head==road->rear) 192 cout<<"便道里没有车!"<<endl; 193 else 194 { 195 cout<<"( 便道位置 车辆号码 )"<<endl; 196 while(p!=NULL) 197 { 198 cout<<"( "<<++i<<" "<<p->num<<" )"<<endl; 199 p=p->next; 200 } 201 } 202 free(p); 203 } 204 205 void Print(CarNode *Car)//打印出站车辆信息 206 { 207 int arr,lea; 208 float t; 209 arr=Car->arrive; 210 lea=Car->leave; 211 t=(lea-arr)*cost; //(离开时刻-到达时刻)*停车费 212 cout<<"( 车辆的号码 进库时刻 离开时刻 车费(元) )"<<endl; 213 cout<<"( "<<Car->num<<" "<<arr<<" "<<lea<<" "<<t<<" )"<<endl; 214 } 215 216 void Input(InputData *inputdata) 217 { 218 219 int maxsize; 220 cout<<"请输入停车场容量Maxsize: "; 221 do 222 { 223 cin>>maxsize; 224 if (!(maxsize<n&&maxsize>0)) 225 { 226 cout<<"输入过大,请重新输入停车场容量:"; 227 } 228 229 } while (!(maxsize<n&&maxsize>0)); 230 231 int i=0,j=0,k=1; 232 char c ; 233 int nu; 234 CarStack garage,Temp; 235 LinkQueue road; 236 InitStack(&garage,maxsize); 237 InitStack(&Temp,maxsize); 238 InitQueue(&road); 239 240 while(k) 241 { 242 i=0; 243 while(!i) 244 { 245 cout<<"*******************************************************************"<<endl; 246 cout<<" 欢迎光临停车场 "<<endl; 247 cout<<" 本停车场按停留的时间长短交纳费用 "<<endl; 248 cout<<" 请输入车库命令,格式为“出(入)库 车牌号 出(入)库时间” "<<endl; 249 cout<<" A:到达 D:离去 P:查看停车场车辆 W:查看过道车辆 E:输入结束"<<endl; 250 cout<<"*******************************************************************"<<endl; 251 252 cin>>(inputdata->command)>>(inputdata->num)>>(inputdata->t); 253 254 c = inputdata->command; 255 nu = inputdata->num; 256 257 if(c!='A'&&c!='D'&&c!='W'&&c!='P'&&c!='E') 258 { 259 cout<<"命令不正确,请重新输入!"<<endl; 260 i = 0; 261 } 262 else 263 i = 1; 264 } 265 switch(c) 266 { 267 case 'A': 268 GetCarNode(&garage,&road,inputdata,maxsize);//获取车辆信息 269 break; 270 case 'D': 271 PopStack(&garage,&Temp,&road,inputdata);//车出库 272 break; 273 case 'P': 274 InfoStack(&garage);//车库车辆信息 275 break; 276 case 'W': 277 InfoQueue(&road);//便道车辆信息 278 break; 279 case 'E': 280 k=0; 281 break; 282 default:break; 283 } 284 } 285 cout<<endl; 286 cin.clear(); 287 }