c语言版数据结构(奇迹冬瓜)-队列实战(1)离散事件模拟(银行排队)

//c语言版数据结构(奇迹冬瓜)-队列实战(1)离散事件模拟(银行排队)

//------头文件---------

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

//-------宏定义---------

#define TURE 1
#define ERROR 0
#define OVERFLOW -2

//------替换及结构体------

typedef int Bool;

typedef struct Node
{
	long OccurTime;
	long LeaveTime;
	struct Node *next;
}Custom,*Customer;//模拟顾客属性

typedef struct
{
	Customer front;//头
	Customer rear;//尾
}LinkQueue;//顾客队列化

//-----全局变量-------

long TotalTime,TotalCustomer;//总时间,总客户量
long OpenTime=420,CloseTime=1020;//银行开门时间和关门时间分别是420/60=7:00 1020/60=17:00 以24小时制计算
LinkQueue q[5];//银行开4个普通窗口,一个应急窗口

//------函数列表------

Bool InitQueue();//初始化队列
Bool DeQueue(int i,Customer c);//离开队列
Bool EnQueue(int i,Customer c);//进入队列
void OpenForDay();//初始化数据
//void Bank(Customer c,long *StartTime);
void CompareTime(Custom c);
void QueueLeagth(int *i);
void Bank_Simulation();
void Rand(Customer c,long *StartTime); 

//-------主函数------

void main()
{
	printf("--------------------系统说明-----------------------\n");
	printf("1.关于银行业务系统的模拟.\n");
	printf("2.银行的营业时间为7:00-17:00.\n");
	printf("3.银行有四个窗口对外接待顾客.\n");
	printf("4.窗口在某一时刻只能接待一位顾客,因此在客户众多的情况下需要排队等候.\n");
	printf("5.若两个窗口均被占,则客户排在最短的窗口.\n");
	printf("6.银行办理业务的时间为10-30分钟不等.\n");
	Bank_Simulation();
	printf("平均每个人在银行的逗留时间:");
	printf("%-5.2f\n",(float)TotalTime/TotalCustomer);
	getchar();
	getchar();
}

//-------其余函数--------

void Bank_Simulation()
{
	Custom c;//定义一个顾客
	long StartTime=420;
	int i=1;
	OpenForDay();
	Rand(&c,&StartTime);
	printf("等待时间\t业务办理时间\t窗口号\t\t到达时间\t离开时间\n");
	while(c.LeaveTime<1020)
	{
		CompareTime(c);
		QueueLeagth(&i);
		EnQueue(i,&c);
		StartTime=c.OccurTime;
		printf("%d\t\t",i);
		printf("%d:%d\t\t",c.OccurTime/60,c.OccurTime%60);
		printf("%d:%d\n",c.LeaveTime/60,c.LeaveTime%60);
		getchar();
		Rand(&c,&StartTime);
	}
}

void OpenForDay()
{
	//int i;
	TotalTime=0;
	TotalCustomer=0;
	InitQueue();
}

void Rand(Customer c,long *StartTime)
{
	srand((unsigned)time(NULL));
	do
	{
		c->OccurTime=rand()%1020;

	}while(c->OccurTime<*StartTime);
}

Bool InitQueue()
{
	int i=1;
	for(;i<=4;i++)
	{
		q[i].rear=q[i].front=(Customer)malloc(sizeof(Custom));
		if(!q[i].front)
		{
			exit(OVERFLOW);
		}
		q[i].front->next=NULL;
	}
	return TURE;
}

Bool DeQueue(int i,Customer c)
{
	Customer t=(Customer)malloc(sizeof(Custom));
	if(!t||q[i].front==q[i].rear)
	{
		exit(OVERFLOW);
	}
	t=q[i].front->next;
	c->OccurTime=t->OccurTime;
	c->LeaveTime=t->LeaveTime;
	q[i].front->next=t->next;
	if(q[i].rear==t)
	{
		q[i].rear=q[i].front;
	}
	free(t);
	return TURE;
}

Bool EnQueue(int i,Customer c)
{
	long DurTime,WaitTime=0;
	Customer t=(Customer)malloc(sizeof(Custom));
	if(!t)
	{
		exit(OVERFLOW);
	}
	if(q[i].front==q[i].rear)
	{
		WaitTime=0;
	}
	else
	{
		WaitTime=q[i].rear->LeaveTime-q[i].rear->OccurTime;
	}
	srand((unsigned)time(NULL));
	do
	{
		DurTime=rand()%31;

	}while(DurTime<10);
	c->LeaveTime=c->OccurTime+WaitTime+DurTime;
	printf("%ld\t\t%ld\t\t",WaitTime,DurTime);
	t->OccurTime=c->OccurTime;
	t->LeaveTime=c->LeaveTime;
	TotalTime+=c->LeaveTime-c->OccurTime;
	t->next=NULL;
	q[i].rear->next=t;
	q[i].rear=t;
	TotalCustomer++;
	return TURE;
}

void CompareTime(Custom c)
{
	int i;
	Custom t;
	Customer s;
	for(i=1;i<=4;i++)
	{
		s=q[i].front->next;
		while(s&&q[i].front!=q[i].rear)
		{
			if(c.OccurTime>=s->LeaveTime)
			{
				DeQueue(i,&t);
				s=q[i].front->next;
			}
			else
			{
				s=s->next;
			}
		}
	}
}

void QueueLeagth(int *i)
{
	int min,j,k,a[4];
	Customer s;
	for(j=0;j<4;j++)
	{
		k=0;
		s=q[j+1].front;
		if(q[j+1].front==q[j+1].rear)
		{
			a[j]=0;
		}
		else
		{
			while(s!=q[j+1].rear)
			{
				s=s->next;
				a[j]=++k;
			}
		}
	}
	min=a[0];
	*i=1;
	for(j=0;j<4;j++)
	{
		if(min>a[j])
		{
			min=a[j];
			*i=j+1;
		}
	}
}


 

 

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: 在 C 语言中,可以使用递归的方式来对二叉树进行层次遍历。 首先,需要定义一个二叉树的结构体: ``` struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; ``` 然后,可以定义一个递归函数,用于遍历二叉树的每一层: ``` void traverseLevel(struct TreeNode *root, int level) { if (root == NULL) { return; } if (level == 1) { // 在这里处理当前节点的值 } else { // 递归遍历左子树和右子树 traverseLevel(root->left, level - 1); traverseLevel(root->right, level - 1); } } ``` 最后,可以调用这个函数,按层次遍历整棵二叉树: ``` void traverse(struct TreeNode *root) { int height = getTreeHeight(root); for (int i = 1; i <= height; i++) { traverseLevel(root, i); } } ``` 其中,getTreeHeight 函数用于计算二叉树的高度,可以使用递归的方式来实现。 示例代码如下: ``` #include <stdio.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; int getTreeHeight(struct TreeNode *root) { if (root == NULL) { return 0; } int leftHeight = getTreeHeight(root->left); int rightHeight = getTreeHeight(root->right); return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1; } void traverseLevel(struct TreeNode *root, int level) { if (root == NULL) { return; } if (level == 1) { printf("%d ", root->val); } else { traverseLevel(root->left, level - 1); traverseLevel(root->right, level - 1); } } void traverse(struct TreeNode *root) { int height = getTreeHeight(root); for (int i = 1 ### 回答2: 使用递归方式实现二叉树的层次遍历较为困难,一般情况下需要借助队列来进行辅助。因为二叉树的层次遍历需要按照顺序来遍历每一层的节点。 递归的思想是通过逐层递归地遍历树的节点,但是这种方式无法保证按层次遍历。 如果要求使用递归而不使用队列,可以使用递归来遍历每一层的节点,并将每一层的节点值存放在一个二维数组中。 具体实现如下: ```c #include <stdio.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void getHeight(struct TreeNode* root, int *max_height) { if (root == NULL) return; getHeight(root->left, max_height); getHeight(root->right, max_height); (*max_height)++; // 计算树的高度 } // 递归函数,将节点值按照层次存放在二维数组中 void levelOrder(struct TreeNode* root, int **result, int level) { if (root == NULL) return; result[level-1] = (int*)realloc(result[level-1], (level * sizeof(int))); // 分配内存 result[level-1][level-1] = root->val; // 存放节点值 levelOrder(root->left, result, level+1); // 递归遍历每一层的左子树节点 levelOrder(root->right, result, level+1); // 递归遍历每一层的右子树节点 } int** levelOrderTraversal(struct TreeNode* root, int* returnSize, int** returnColumnSizes) { int max_height = 0; getHeight(root, &max_height); // 计算二叉树的高度 int **result = (int**)malloc(max_height * sizeof(int*)); // 二维数组,存放树的节点值 *returnSize = max_height; // 返回的行数为树的高度 for (int i = 0; i < max_height; i++) { result[i] = NULL; // 初始化二维数组,置为NULL } levelOrder(root, result, 1); // 递归遍历二叉树的每一层节点 *returnColumnSizes = (int*)malloc(max_height * sizeof(int)); // 一维数组,存放每一层的列数 for (int i = 0; i < max_height; i++) { (*returnColumnSizes)[i] = i+1; // 每一层的列数为i+1 } return result; } ``` 这种方法虽然使用了递归,但是需要动态分配内存,内存的分配和释放需要注意。而且每次遍历时都需要判断节点的高度,效率较低。所以在实际应用中,使用队列来实现二叉树的层次遍历更为常见和高效。 ### 回答3: 要使用C语言实现二叉树层次遍历,可以使用递归的方式来实现。通常情况下,二叉树的层次遍历需要借助队列来进行操作,但是在此要求不使用队列的情况下,可以使用递归的方式来进行。 首先,我们需要确定遍历的顺序,层次遍历是从上到下,从左到右的顺序。所以我们可以定义一个函数`levelTraversal`来进行层次遍历。函数的参数包括二叉树的根节点指针和当前层的层数。 在函数内部,我们首先判断根节点是否为空,若为空则直接返回。然后,我们判断当前层是否为1,如果是1层则输出当前节点的值。接下来,我们对当前节点的左子树调用`levelTraversal`函数,将层数参数加1,并对右子树也进行同样的操作。 这样就实现了递归的层次遍历,具体代码如下: ``` #include <stdio.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void levelTraversal(struct TreeNode* root, int level) { if (root == NULL) { return; } if (level == 1) { printf("%d ", root->val); } levelTraversal(root->left, level - 1); levelTraversal(root->right, level - 1); } int getBinaryTreeHeight(struct TreeNode* root) { if (root == NULL) { return 0; } else { int left_height = getBinaryTreeHeight(root->left); int right_height = getBinaryTreeHeight(root->right); return (left_height > right_height) ? (left_height + 1) : (right_height + 1); } } void levelOrder(struct TreeNode* root) { int height = getBinaryTreeHeight(root); for (int i = 1; i <= height; i++) { levelTraversal(root, i); } printf("\n") } ``` 在这段代码中,我们定义了一个辅助函数`getBinaryTreeHeight`来获取二叉树的高度。然后,我们在`levelOrder`函数中进行层次遍历。遍历的范围是从第1层到二叉树的高度,对每一层都调用`levelTraversal`函数进行遍历。 注意,在实际使用中,我们需要根据自己的需求来处理节点的值,例如输出、存储等等。以上为一个简单的实现,希望对你有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值