1、停车。 当车位已满的时候,车辆进行排队。
2、车离开。车离开后,计算其使用时间。如果等待区有车辆,则进入停车场停车。
3、查看当前停车场的使用情况。
1、停车区通过顺序栈来实现,一个停车栈,一个让车栈。这样可以保证随机离开车库中的车辆,实际生活中当然没有这个操作,但是由于栈的性质(只能对栈顶元素进行操作,不能直接随机增删其他元素),只能多此一举。
2、等待区通过链式队列来实现(先来先进)。链式结构很方便,需要多少内存,再分配多少内存。
1、停车时,如何保证随机停入空车位?
2、如何保证车离开后,其他的车的车位号不变?
1、核心:如果有N个车位,停车栈初始化时增加N个含有对应车位号的元素
1、函数传参时,如果要修改顺序栈的值需要传指针拷贝,不需要或者不能改变值时需要顺序栈内存空间的一份拷贝。
1、函数传参时,如果要修改链式队列的值需要传指针拷贝,不需要或者不能改变值时需要链式队列内存空间的一份拷贝。
#ifndef _CAR_H_
#define _CAR_H_
typedef enum{FALSE,TRUE} BOOL;
enum{PARK = 1,LEAVE,DISPALY} ;
//时间
typedef struct _time
{
int year;
int mon;
int day;
int hour;
int min;
int sec;
}Time;
// 车信息
typedef struct _data
{
int num_plate; //车牌号
int park_num; //车位号
int wait_num; //等车号
Time start_time; //开始时间
}Data;
#endif //_CAR_H_
#ifndef _STACK_H_
#define _STACK_H_
#include "car.h"
#define STACK_SIZE 10
//停车和让车栈 === 顺序栈
typedef struct _stack
{
Data data[STACK_SIZE]; //停车场的车位数
int top ; //栈顶下标
}Stack;
//初始化空栈
void Init_Stack(Stack*s);
//判断满栈
BOOL IsFull_Stack(Stack*s);
//入栈
void Push_Stack(Stack*s,Data data);
//判断空栈
BOOL IsEmpty_Stack(Stack*s);
//出栈
void Pop_Stack(Stack*s);
//获取栈顶元素
Data Gettop(Stack*s);
//打印车的信息
void print_car(Data*data);
//打印栈数据
void Display_Stack(Stack*s);
#endif//_STATCK_H_
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include "car.h"
typedef struct _node
{
Data data; //节点数据
struct _node *next ; //指针域 指向下一个节点
}Node;
typedef struct _queue
{
Node *front;
Node *rear;
}Queue;
//初始化空队列
void Init_Queue(Queue*q);
//判断空队列
BOOL IsEmpty_Queue(Queue*q);
//入队列
void Push_Queue(Queue*q,Data data);
//出队列
void Pop_Queue(Queue*q);
//获取队头元素
Data GetFront(Queue*q);
//打印队列数据
void Display_Queue(Queue*q);
#endif//_QUEUE_H_
#ifndef _PARK_H_
#define _PARK_H_
#include "Queue.h"
#include "stack.h"
#include "car.h"
//获取时间
Time Gettime();
//计算两段时间差值
Time minus_time(Time time1,Time time2);
// 计算等待区的车辆数
// 计算排队人数
int calwaitlen(Queue wait_queue);
// 计算剩余空车位
int Use_State(int use_flag[], int Isprint);
//找到对牌号的位置 //从栈顶开始数
int car_place(Stack park_stack,int park_num);
//停车
void park(Stack*park_stack,Stack*mid_stack,Queue*wait_queue,Data*data_init,int*use_flag);
//离开
void leave(Stack*park_stack,Stack*mid_stack,Queue*wait_queue,int*use_flag);
//查看停车场信息
void show_park(Stack park_stack,Stack mid_stack, Queue wait_queue,int*use_flag);
//UI
void UI();
//主界面
void menu();
#endif //_PARK_H_
#include "stack.h"
#include
#include
void Init_Stack(Stack*s)
{
if(NULL == s)
return ;
s->top = -1;
}
BOOL IsFull_Stack(Stack*s)
{
if(NULL == s)
return ;
if(STACK_SIZE-1 == s->top)
return TRUE;
return FALSE;
}
void Push_Stack(Stack*s,Data data)
{
if(NULL == s)
return ;
if(IsFull_Stack(s) == TRUE)
return ;
s->data[++s->top] = data;
}
BOOL IsEmpty_Stack(Stack*s)
{
if(NULL == s)
return ;
if(-1 == s->top)
return TRUE;
return FALSE;
}
void Pop_Stack(Stack*s)
{
if(NULL == s)
return ;
if(IsEmpty_Stack(s) == TRUE)
return ;
s->top--;
}
Data Gettop(Stack*s)
{
if(NULL == s)
return ;
if(IsEmpty_Stack(s) == TRUE)
exit(-1) ;
return s->data[s->top];
}
void print_car(Data *data)
{
int year = data->start_time.year;
int mon = data->start_time.mon;
int day = data->start_time.day;
int hour = data->start_time.hour;
int min = data->start_time.min;
int sec = data->start_time.sec;
if(data->park_num != 0)
printf("车位号:%-d\t",data->park_num);
printf("车牌号:");
if(data->num_plate != 0)
printf("%-d\t",data->num_plate);
if(data->start_time.sec == 0)
printf("\t停入时间:");
else
printf("停入时间: %4d年%2d月%2d日%2d时%2d分%2d秒\t",year,mon,day,hour,min,sec);
printf("\n");
}
void Display_Stack(Stack*s)
{
while(!IsEmpty_Stack(s))
{
Data top = Gettop(s);
print_car(&top);
Pop_Stack(s);
}
}
#include "Queue.h"
#include
#include
void Init_Queue(Queue*q)
{
if(NULL == q)
return ;
q->front = NULL;
q->rear = NULL;
}
BOOL IsEmpty_Queue(Queue*q)
{
if(NULL == q)
return ;
if(NULL == q->front)
return TRUE;
return FALSE;
}
void Push_Queue(Queue*q,Data data)
{
if(NULL == q)
return ;
Node *new_node =(Node*)malloc(sizeof(Node)/sizeof(char));
if(NULL == new_node)
{
return ;
}
new_node->data = data;
new_node->next = NULL;
if(!IsEmpty_Queue(q))//非空队列
{
q->rear ->next = new_node;
q->rear = new_node;
}
else//空队列
{
q->front = new_node;
q->rear = new_node;
}
}
void Pop_Queue(Queue*q)
{
if(NULL == q)
return ;
if(IsEmpty_Queue(q) == TRUE)
return ;
Node *tmp = q->front;
if(q->front->next != NULL)//队列 > 1个节点
{
q->front = tmp->next;
}
else//队列 = 1个节点
{
q->front = NULL;
q->rear = NULL;
}
free(tmp);
}
Data GetFront(Queue*q)
{
if(NULL == q)
return ;
if(IsEmpty_Queue(q) == TRUE)
exit(-1) ;
return q->front->data;
}
void Display_Queue(Queue*q)
{
while(!IsEmpty_Queue(q))
{
Pop_Queue(q);
}
printf("\n");
}
#include
#include
#include
#include "stack.h"
#include "Queue.h"
#include "Park.h"
#include "string.h"
//时间
Time Gettime()
{
time_t timep;
struct tm *p;
time (&timep);
p=gmtime(&timep);
Time cue_time;
cue_time.year = 1900+p->tm_year;
cue_time.mon = 1+p->tm_mon;
cue_time.day = p->tm_mday;
cue_time.hour = p->tm_hour+8;
cue_time.min = p->tm_min;
cue_time.sec = p->tm_sec;
//int use_time = p->tm_sec+p->tm_min*60+(p->tm_hour+8)*3600;
// printf("%d:%d:%d:%d:%d:%d\n",1900+p->tm_year,1+p->tm_mon,p->tm_mday,p->tm_hour+8,p->tm_min,p->tm_sec);
return cue_time;
}
//计算两段时间差值
Time minus_time(Time time1,Time time2)
{
Time res_time = {0};
//秒
if(time1.sec<time2.sec)
{
time1.min--;
res_time.sec = time1.sec+60-time2.sec;
}
else
{
res_time.sec = time1.sec-time2.sec;
}
//分钟
if(time1.min<time2.min)
{
time1.hour--;
res_time.min = time1.min+60-time2.min;
}
else
{
res_time.min = time1.min-time2.min;
}
//小时
if(time1.hour<time2.hour)
{
time1.day--;
res_time.hour = time1.hour+24-time2.hour;
}
else
{
res_time.hour = time1.hour-time2.hour;
}
//日
if(time1.day<time2.day)
{
time1.mon--;
res_time.day = time1.day+30-time2.day;//当三十天算
}
else
{
res_time.day = time1.day-time2.day;
}
//月
if(time1.mon<time2.mon)
{
time1.year--;
res_time.mon = time1.mon+12-time2.mon;
}
else
{
res_time.mon = time1.mon-time2.mon;
}
//年
res_time.hour = time1.hour-time2.hour;
return res_time;
}
// 计算等待区的车辆数
// 计算排队人数
int calwaitlen(Queue wait_queue)
{
int wait_len = 1;
if(wait_queue.front == NULL)
{
wait_len = 0;
return wait_len;
}
while(wait_queue.front != wait_queue.rear)
{
wait_len++;
wait_queue.front = wait_queue.front->next;
}
return wait_len;
}
// 计算剩余空车位
int Use_State(int use_flag[], int Isprint)
{
int remain_count = 0; //剩余空车位
int i;
for(i=0;i<STACK_SIZE;i++)
{
if(0 == use_flag[i])
{
remain_count++;
if(Isprint == 1)//需要打印空车位
printf("车位:%-d\n",i+1);
}
}
return remain_count;
}
//找到对牌号的位置 //从栈顶开始数
int car_place(Stack park_stack,int num_plate)
{
if(IsEmpty_Stack(&park_stack))
{
printf("停车场没有车\n");
return -1;
}
int place = 1;
while(!IsEmpty_Stack(&park_stack))
{
Data data = Gettop(&park_stack);
Pop_Stack(&park_stack);
if(data.num_plate == num_plate)
{
return place;
}
else
{
place++;
}
}
return 0; //没找到返回0
}
//查看停车场信息
void show_park(Stack park_stack,Stack mid_stack, Queue wait_queue,int*use_flag)
{
printf("###############################[停车场使用情况]#################################\n");
printf("信息一:\t停车场共有车位: %d\n",STACK_SIZE);
printf("信息二:\t当前已使用车位: %d\n",STACK_SIZE-Use_State(use_flag,0));
printf("信息三:\t等待区现有车辆: %d \n",calwaitlen(wait_queue));
printf("###############################[停车场使用情况]#################################\n");
printf("\n");
printf("-----------------------------------[停车场]-------------------------------------\n");
Display_Stack(&park_stack);
printf("-----------------------------------[停车场]-------------------------------------\n");
if(!IsEmpty_Queue(&wait_queue))
{
printf("-----------------------------------[等待区]-------------------------------------\n");
//记录原来等待队列的长度
int waitlen = calwaitlen(wait_queue);
while(waitlen>0)
{
Data data = GetFront(&wait_queue);
Pop_Queue(&wait_queue);
waitlen--;
printf("等车号:%-d\t",data.wait_num);
printf("车牌号:%-d\t",data.num_plate);
printf("\n");
//重点!!!!!!!!
//再将pop的数据插到队列的尾部,这样整个查看的过程结束后,保持原来的队列不变。否则整个队列被清空,导致内存错误和逻辑错误。
Push_Queue(&wait_queue,data);
}
printf("-----------------------------------[等待区]-------------------------------------\n");
}
}
//停车
void park(Stack*park_stack,Stack*mid_stack,Queue*wait_queue,Data*data_init,int*use_flag)
{
data_init->num_plate++;
Data data = *data_init;
if(Use_State(use_flag,0) == 0)
{
printf("车位已满,请排队...\n");
data_init->wait_num++;
data = *data_init;
Push_Queue(wait_queue,data);
show_park( *park_stack,*mid_stack, *wait_queue,use_flag);
}
else
{
Use_State(use_flag,1);
int num_car;
printf("请输入停入的车位号 ");
Use_State(use_flag,0);
scanf("%d",&num_car);
//检查输入错误
while(num_car<0 || num_car>STACK_SIZE)
{
printf("本停车场没有此车位!请重新选择: ");
scanf("%d",&num_car);
}
//检查是否有车
while(use_flag[num_car-1] == 1)
{
printf("该车位已经有车! 请重新选车位: ");
scanf("%d",&num_car);
}
//移入让车栈
int num1 = num_car;
while((STACK_SIZE-num1)>0)
{
Push_Stack(mid_stack,Gettop(park_stack));
Pop_Stack(park_stack);
num1++;
}
park_stack->data[park_stack->top].num_plate = data.num_plate;
park_stack->data[park_stack->top].start_time = Gettime();
//修改状态位
use_flag[num_car-1] = 1;
printf("停车成功\n");
//移回停车栈
int num2 = STACK_SIZE-num_car;
while(num2>0)
{
Push_Stack(park_stack,Gettop(mid_stack));
Pop_Stack(mid_stack);
num2--;
}
show_park( *park_stack,*mid_stack, *wait_queue,use_flag);
}
}
//车离开
void leave(Stack*park_stack,Stack*mid_stack,Queue*wait_queue,int*use_flag)
{
show_park(*park_stack,*mid_stack,*wait_queue,use_flag);
if(Use_State(use_flag,0) == STACK_SIZE)
{
printf("停车场没有车\n");
return ;
}
int num_plate ;
printf("请输入要离开车的牌号: ");
scanf("%d",&num_plate);
int palce = car_place(*park_stack,num_plate);
int palce_index = STACK_SIZE - palce;//位置栈的下标
while(0 == palce)
{
system("clear");
printf("提示: 输入[1]退出... \n");
printf("停车场没有车牌号为%d的车\n",num_plate);
printf("请重新输入要离开车的牌号: ");
scanf("%d",&num_plate);
palce = car_place(*park_stack,num_plate);
if(num_plate == 1)
return ;
}
// 将车挪入让车栈
while((palce-1)>0)
{
Push_Stack(mid_stack,Gettop(park_stack));
Pop_Stack(park_stack);
palce--;
}
Time data0 = {0};
Time starttime = Gettop(park_stack).start_time;
Time endtime = Gettime() ;
Time usertime = minus_time(endtime,starttime);
park_stack->data[park_stack->top].num_plate = 0;
park_stack->data[park_stack->top].start_time = data0;
use_flag[palce_index] = 0;
printf("欢迎使用,停车时长为:%d时 %d分 %d秒 \n",usertime.hour,usertime.min,usertime.sec);
//如果等待队列有人
//进入停车
if(!IsEmpty_Queue(wait_queue))
{
Data data = GetFront(wait_queue);
Pop_Queue(wait_queue);
//data.wait_num = 0;
park_stack->data[park_stack->top].num_plate = data.num_plate;
park_stack->data[park_stack->top].start_time = Gettime();
use_flag[park_stack->top] = 1;
}
if(!IsEmpty_Stack(mid_stack))
{
int mid_top = mid_stack->top + 1;
// 将车挪回停车栈
while(mid_top>0)
{
Push_Stack(park_stack,Gettop(mid_stack));
Pop_Stack(mid_stack);
mid_top--;
}
}
system("clear");
show_park( *park_stack,*mid_stack, *wait_queue,use_flag);
}
void UI()
{
printf("*************************\n");
printf("**请输入以下命令: **\n");
printf("**[1] 停车 **\n");
printf("**[2] 离开 **\n");
printf("**[3] 查看停车场信息 **\n");
printf("**按其它键退出 **\n");
printf("*************************\n");
}
//主界面
void menu()
{
// 车位是否被使用的标志位
int use_flag[STACK_SIZE];
//起始数据
Data data_init = {10000,0,0,0};
// 创建空的停车栈
Stack park_stack ;
Init_Stack(&park_stack);
//初始化停车场
Data data = {0,0,0,0};
int i;
for(i=0;i<STACK_SIZE;i++)
{
use_flag[i] = 0;
data.park_num = i+1;
Push_Stack(&park_stack,data);
}
/***********测试用*******************
Data data = {10000,0,0,0};
int i;
for(i=0;i
// 创建让车栈并初始化
Stack mid_stack ;
Init_Stack(&mid_stack);
// 创建等车队列并初始化
Queue wait_queue;
Init_Queue(&wait_queue);
while(1)
{
UI();
int quit = 0;
int cmd = 0;
printf("你输入的命令是: ");
scanf("%d",&cmd);
system("clear");
switch(cmd)
{
case PARK:
park(&park_stack,&mid_stack,&wait_queue,&data_init,use_flag);
break;
case LEAVE:
leave(&park_stack,&mid_stack,&wait_queue,use_flag);
break;
case DISPALY:
show_park(park_stack,mid_stack,wait_queue,use_flag);
break;
default:
quit = 1;
break;
}
while(0 == quit)
{
printf("【提示:按任意键退出...】\n");
getchar();
if(getchar())
break;
}
system("clear");
if(quit)
{
system("clear");
printf("感谢使用,祝您生活愉快!!!\n");
return;
}
}
}
#include
#include "stack.h"
#include "Queue.h"
#include "Park.h"
int main()
{
Gettime();
menu();
return 0;
}