栈和队列模拟停车场管理系统V2.0

文章目录

  • 实现功能
  • 知识要点
  • 重点难点
    • 个人解决方案:
      • 注意:
  • 项目文件
    • 头文件
      • car.h
      • stack.h
      • queue.h
      • park.h
    • C文件
      • stack.c
      • queue.c
      • park.c
      • 主函数

实现功能

1、停车。 当车位已满的时候,车辆进行排队。
2、车离开。车离开后,计算其使用时间。如果等待区有车辆,则进入停车场停车。
3、查看当前停车场的使用情况。

知识要点

1、停车区通过顺序栈来实现,一个停车栈,一个让车栈。这样可以保证随机离开车库中的车辆,实际生活中当然没有这个操作,但是由于栈的性质(只能对栈顶元素进行操作,不能直接随机增删其他元素),只能多此一举。
2、等待区通过链式队列来实现(先来先进)。链式结构很方便,需要多少内存,再分配多少内存。

重点难点

1、停车时,如何保证随机停入空车位?
2、如何保证车离开后,其他的车的车位号不变?

个人解决方案:

1、核心:如果有N个车位,停车栈初始化时增加N个含有对应车位号的元素

栈和队列模拟停车场管理系统V2.0_第1张图片
2、停入和离开时,要进行数据拷贝和初始化。

注意:

1、函数传参时,如果要修改顺序栈的值需要传指针拷贝,不需要或者不能改变值时需要顺序栈内存空间的一份拷贝。
1、函数传参时,如果要修改链式队列的值需要传指针拷贝,不需要或者不能改变值时需要链式队列内存空间的一份拷贝。

项目文件

头文件

car.h

#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_

stack.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_

queue.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_

park.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_

C文件

stack.c

#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);	
	}	
}

queue.c

#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");
}

park.c

#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;
}

你可能感兴趣的:(案例与C语言实现的解决方案)