我的C语言队列练习

本文档介绍了如何使用C语言编写队列数据结构。包括`queue.h`头文件和`queue.c`源代码实现,涵盖了队列的基本操作,如入队、出队等。通过struct定义队列节点,讨论了空队列处理和链表结构的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

资源下载(包含所有代码、MakeFile、以及一份简单描述分析思路和流程图的WORD文档): http://download.youkuaiyun.com/detail/htianlong/4443226
/*************************************************************
题目:电话客户服务模拟
    1、    问题描述
一个模拟时钟提供接听电话服务的时间(以分钟计),然后这个时
钟将循环地自增1(分钟),直到到达指定的时间为止。在时钟的每
个“时刻”,就会执行一次检查来看看当前电话的服务是否已经完成,
如果是,这个电话从电话队列中删除,模拟服务将从队列中取出下
一个电话(如果有)继续开始。同时还需要执行一个检查来判断是
否有一个新的电话到达,如果有将其到达的时间记录下来,并为其
产生一个随机服务时间,这个服务时间也被记录下来,然后将这个
电话放入电话队列中,当客户服务人员空闲时,按照先来先服务的
方式处理这个队列。当时钟到达指定时间时,不会再接听新电话,
但是服务将继续,直到队列中所有电话得到处理为止。
    2、    要求
    (1)    程序需要处理的初始数据包括:客户服务人员的人数
、时间限制,电话到达的速率,平均服务时间。
    (2)    程序产生的结果包括:处理的电话数,每个电话的平
均等待时间
运行环境:Linux
Linux下调试通过。
*************************************************************/
#include <stdio.h>
#include <time.h>
#include "queue.h"
/**需要输入的数据*/
int customer_service_staff_num = 5;//客户服务人员的人数
time_t time_limite = 20;//时间限制
double telephone_rate = 60.0/60;//电话到达的速率
/*此处为简化程序默认通电时间在0到2倍平均时间之间均匀分布*/
int average_service_time = 10;//平均服务时间
/**其他全局变量*/
time_t start_time;//记录开始时间
time_t t;//上次时间
int period_time;//电话到达的周期
time_t rawtime;//当前时间,以秒计,从1970年1月一日起算
queue tel_wait_que;//电话等待队列
int wait_time_sum  = 0;//等待时间
int phone_sum = 0;//电话计数
int phone_service_finished = 0;//电话服务是否全部完成?1:未完成;0:完成
/**题目中所指的电话队列指的不可能是计算机用语中的队列,因为删除的不是总在开头*/
time_t *tel_que;//“电话队列”指针

void init()//初始化
{
    int i;
    system("clear");
    printf("请输入客户服务人员的人数(建议输入5)\n");
    scanf("%d", &customer_service_staff_num);
    printf("请输入时间限制(建议输入20)(单位为分钟,此程序的1分钟为现实中的1秒)\n");
    scanf("%ld", (long *)&time_limite);
    printf("请输入电话到达的速率,指平均每分钟到达的电话数,取值范围(0,1](建议输入1)\n");
    scanf("%lf", &telephone_rate);
    printf("请输入平均服务时间(单位:分钟)(建议输入10)\n");
    scanf("%d", &average_service_time);
    tel_wait_que = queue_init(NULL);//电话等待队列初始化
    queue_print(tel_wait_que, queuedata_print_phonedata);//打印当前电话服务状态信息
    tel_que = (time_t *)malloc((sizeof(time_t)) * customer_service_staff_num);//初始化电话“队列”(实际为数组)的结构
    for (i = 0; i < customer_service_staff_num; i++)//初始化“电话队列”的值为0。
    {
        tel_que[i] = 0;//0:表示当前电话无服务进行or电话服务正好结束
    }
    period_time = 1.0 / (double)telephone_rate;//初始化电话到达的周期
    time(&rawtime);//获取当前时间
    t = rawtime;//设置上次获取的时间
    start_time = t;//设置服务开始时间
}
void check_new_tel()//检查是否有新的电话到达
{
    if (0 == (rawtime % period_time) && (start_time + time_limite - t) > 0)//到达循环周期,收到电话。且必须满足条件“在时间限制之内”
    {
        queuedata qdata;
        qdata.arrive_time = rawtime;//保存当前时间
        qdata.service_time = (time_t)rand() % (average_service_time*2)+1;//分配随机服务时间
        queue_push(tel_wait_que, qdata);//将新电话加入电话等待队列
        phone_sum++;//电话数加一
    }
}
void check_phone_service_finish()//检查电话服务是否完成,如果完成,则将电话从电话队列中删除,
{
    //模拟服务将从队列中取出下一个电话(如果有)继续开始。
    int i;
    queuedata qdata;
    phone_service_finished = 1;
    for(i = 0; i < customer_service_staff_num; i++)//依次检查是否有电话空闲
    {
        if (tel_que[i] == 0)//客户服务人员空闲
        {
            if (queue_isempty(tel_wait_que) == 0)//有电话
            {
                queue_pop(tel_wait_que,&qdata);//从电话等待队列中取出第一个电话

                wait_time_sum += (rawtime - qdata.arrive_time);//等待时间总和加上当前时间减去到达时间的差即当前电话等待时间
                tel_que[i] = qdata.service_time;//倒计时赋初值 为服务时间
            }

        }
        else//只要有一个客服服务人员没空闲 phone__service_finished 就是0
        {
            phone_service_finished = 0;//电话服务没全部完成
        }
    }
}
void phone_service_stat_print()//打印当前电话服务的状态信息
{
    int i;
    printf("各电话分机接听电话剩余时间\n");
    for (i = 0; i < customer_service_staff_num; i++)
    {
        printf("%ld\t",(long)tel_que[i]);
    }
}
void time_going()//时间流逝————将倒计时减一直到倒计时为0
{
    int i;
    for (i = 0; i < customer_service_staff_num; i++)
    {
        if (tel_que[i] > 0)
        {
            tel_que[i]--;
        }
    }
}
void service_circle()
{
    while(((start_time + time_limite - t) > 0) || (phone_service_finished == 0))//如果没到时间限制 或者 电话服务没有全部完成
    {
        time( &rawtime );//获取当前时间
        if (t != rawtime)//当前时间不等于上次获取时间 即表示进入下一秒了
        {
            system("clear");
            printf("开始时间:");
            time_t_print(start_time);
            printf("\n当前时间:");
            time_t_print(rawtime);
            printf("\n截止时间:");
            time_t_print(start_time + time_limite);
            printf("\n预计处理的电话数为%d,等待总时间累计为%d分钟\n", phone_sum, wait_time_sum);
            t = rawtime;//设置上次获取时间
            srand( time(NULL) );
            rand();
            time_going();//时间流逝————倒计时减一
            check_new_tel();//检查是否有新的电话到达
            check_phone_service_finish();//检查电话服务是否完成,如果完成,则将电话从电话队列中删除,
            //模拟服务将从队列中取出下一个电话(如果有)继续开始。
            phone_service_stat_print();//打印当前电话服务的状态信息
            printf("\n电话等待队列:\n");
            queue_print(tel_wait_que, queuedata_print_phonedata);
        }
    }
}
void result_print()//打印结果
{
    printf("\n全部处理完成。\n处理的电话数为%d,每个电话的平均等待时间为%f分钟\n", phone_sum, (float)wait_time_sum/(float)phone_sum);
}
int main(void)
{
    init();//初始化
    service_circle();//服务循环开始
    result_print();//电话服务结果打印
    return 0;
}


queue.h:

#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED

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

#define QUEUESIZE 100
typedef struct
{
    time_t arrive_time;
    time_t service_time;
}queuedata;
typedef struct QUEUE
{
    queuedata qdata[100];
    int start;
    int end;
}Queue;

typedef Queue *queue;

queue queue_init(queue que);
int queue_isempty(queue que);
int queue_isfull(queue que);
int queue_push(queue que, queuedata data);
int queue_pop(queue que, queuedata *ch);
int queue_getstart(queue que, queuedata *ch);
void queue_print(queue que, void (*print)(void *));
void queuedata_print_phonedata(void *qdata);
#endif // QUEUE_H_INCLUDED

queue.c:

#include "queue.h"
queue queue_init(queue que)
{
    if (que == NULL)
    {
        queue que= (queue)malloc(sizeof(Queue));
        que->start = 0;
        que->end = 0;
        return que;
    }
    else
    {
        que = (queue)malloc(sizeof(Queue));
        que->start = 0;
        que->end = 0;
        return que;
    }

}
int queue_isempty(queue que)
{
    if (que->start == que->end)
    {
//        printf("the queue is empty\n");
        return 1;
    }
    else
    {
        return 0;
    }
}
int queue_isfull(queue que)
{
    if ((que->end +1)%QUEUESIZE == que->start)
    {
//        printf("the queue is full!\n");
        return 1;
    }
    else
    {
        return 0;
    }
}
int queue_push(queue que, queuedata data)
{
    if (queue_isfull(que) == 1)
    {
        return -1;
    }
    que->qdata[que->end] = data;
    que->end++;
    if (que->end == 100)
    {
        que->end = 0;
    }
    return 0;
}
int queue_pop(queue que, queuedata *ch)
{
    if (queue_isempty(que) == 1)
    {
        return -1;
    }
    *ch = que->qdata[que->start];
    que->start++;
    if (que->start == 100)
    {
        que->start = 0;
    }
    return 0;
}
int queue_getstart(queue que, queuedata *ch)
{
    if (queue_isempty(que) == 1)
    {
        return -1;
    }
    *ch = que->qdata[que->start];
    return 0;
}
void queue_print(queue que, void (*print)(void *))
{
    int i;
    if (queue_isempty(que) == 1)
    {
        return;
    }
    if (que->start < que->end)
    {
        for (i = que->start; i < que->end; i++)
        {
            (*print)((void*)&que->qdata[i]);
        }
    }
    else
    {
        for (i = que->start; i < 100; i++)
        {
            (*print)((void*)&que->qdata[i]);
        }
        for (i = 0; i < que->end; i++)
        {
            (*print)((void*)&que->qdata[i]);
        }
    }
    printf("\n");
    return ;
}
void time_t_print(time_t t)
{
    struct tm *p;
    char *weekdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    p = localtime(&t);
    printf("%d/%d/%d ", (1900+p->tm_year), (1 + p->tm_mon), p->tm_mday);
    printf("%s %d:%d:%d", weekdays[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
}

void queuedata_print_phonedata(void *qdata)
{
    printf("到达时间:");
    time_t_print(((queuedata*)qdata)->arrive_time);
    printf("  随机分配服务时间:%ld分钟\n", ((queuedata*)qdata)->service_time);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值