数据结构与算法之队列

1. 队列的定义与操作

1.1 队列的定义

插入(入队)在一端(末尾)进行而删除(出列)在另一端(队首)进行的线性表。即Fist in First out:先进先出的线性表
线性表:a0,a1,a2,a3…an的入队与出队

1.2 队列的基本操作

  1. 入队操作:将数据元素插入队尾
  2. 出队操作:移除队首的数据元素
  3. 是否为空:判断队中实际包含数据元素的个数
  4. 清空操作:移除队中的所有数据元素
  5. 清空操作:移除队列中的所有数据元素
  6. 获取队首元素:

2. 队列的表示与实现

2.1 顺序存储实现

  1. 循环队列(顺序存储):利用数组采用循环的方式实现队列,还必须要附设两个指针front和rear分别指向队列头元素和队列尾元素的位置。
  • 形象演示
  1. 链队列(链存储):利用单链表实现的队列;

3. 练习

1. 模拟银行服务完成程序代码。

目前,在以银行营业大厅为代表的窗口行业中大量使用排队(叫号)系统,该系统完全模拟了人群排队全过程,通过取票进队、排队等待、叫号服务等功能,代替了人们站队的辛苦。

排队叫号软件的具体操作流程为:

  1. 顾客取服务序号
    当顾客抵达服务大厅时,前往放置在入口处旁的取号机,并按一下其上的相应服务按钮,取号机会自动打印出一张服务单。单上显示服务号及该服务号前面正在等待服务的人数。

  2. 服务员工呼叫顾客
    服务员工只需按一下其柜台上呼叫器的相应按钮,则顾客的服务号就会按顺序的显示在显示屏上,并发出“叮咚”和相关语音信息,提示顾客前往该窗口办事。当一位顾客办事完毕后,柜台服务员工只需按呼叫器相应键,即可自动呼叫下一位顾客。

编写程序模拟上面的工作过程,主要要求如下:

程序运行后,当看到“请点击触摸屏获取号码:”的提示时,只要按回车键,即可显示“您的号码是:XXX,您前面有YYY位”的提示,其中XXX是所获得的服务号码,YYY是在XXX之前来到的正在等待服务的人数。
用多线程技术模拟服务窗口(可模拟多个),具有服务员呼叫顾客的行为,假设每个顾客服务的时间是10000ms,时间到后,显示“请XXX号到ZZZ号窗口!”的提示。其中ZZZ是即将为客户服务的窗口号。

2.代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "queue.h"
#include <time.h>

 
int g_number = 0;
 
int add_queue(SEQQUEUE *queue)
{
    int ret = 0;
    int number = 0;
    DATATYPE_T data;
    
    ret = queue_full(queue);
    if(ret==0)
    {
        data.number = ++g_number;
        data.time = time(NULL);
        queue_push(queue,data);
    }
    else
    {
        printf("line up too much,please waiting\n");
        return -1;
    }
    return 0;
}

int next(SEQQUEUE *queue)
{
    int ret = 0;
    DATATYPE_T *data;
    ret = queue_empty(queue);
    if(ret)
    {
        printf("the queue is empty\n");
        return -1;
    }
    
    data = queue_pop(queue); 
    printf("0x%x\n",data);
    printf("please number is %d handles the service\n",data->number);
}
 
void menu()
{
    printf("********************\n");
    printf("1.new consumer\n");
    printf("2.next consumer\n");
    printf("0.quit ");
    printf("\n");
    printf("********************\n");
	
}
 
int main()
{
    int opt = 0;
    int len = 0;
    DATATYPE_T data;
    SEQQUEUE *queue=NULL; 
 
    queue = queue_init();
    if(queue==NULL)
    {
        printf("creat queue failed\n");
        return -1;
    }
 
    do
    {
        menu();
        printf("please input select!\n");
        scanf("%d",&opt);
 
        switch(opt)
        {
            case 1:
                add_queue(queue);
                len = get_queue_length(queue);
                printf("current wait for %d consumer\n",len);
                break;
            case 2:
                next(queue);
                len = get_queue_length(queue);
                printf("current wait for %d consumer\n",len);                
                break;
            case 0:
                break;
            default:
                break;
        }
 
    }while(opt!=0);
    
    return 0;
}



头文件

#ifndef _SEQQUEUE_H_
#define _SEQQUEUE_H_
 
#define QUEUE_MAX    15 // 宏定义

// 队列结构实现 
typedef struct
{
    int number;   //顾客编号
    long time;//进入时间
}DATATYPE_T;
 
typedef struct
{
    DATATYPE_T  data[QUEUE_MAX];  //队列数组
    int head;                     //队列头
    int tail;                     //队列尾
}SEQQUEUE;
 
/*队列是否为空*/
int queue_empty(SEQQUEUE *queue);
 
/*队列是否满*/
int queue_full(SEQQUEUE *queue);
 
/*队列初始化*/
SEQQUEUE *queue_init();
 
/*进队列*/
int queue_push(SEQQUEUE *queue,DATATYPE_T  data);
 
/*出队列*/
DATATYPE_T *queue_pop(SEQQUEUE *queue);
 
/* 获取队列的第一个元素*/
DATATYPE_T *get_queue_first_element(SEQQUEUE *queue);
 
/*获取队列的长度*/
int get_queue_length(SEQQUEUE *queue);
 
/*释放队列*/
void queue_free(SEQQUEUE *queue);
 
/*显示队列信息*/
int show_queue_info(SEQQUEUE *queue);
#endif


//函数实现
 
/*队列是否为空*/
int queue_empty(SEQQUEUE *queue)
{
    return (queue->head==queue->tail);
}
 
/*队列是否满*/
int queue_full(SEQQUEUE *queue)
{
    return (queue->tail==QUEUE_MAX);
}
 
/*队列初始化*/
SEQQUEUE *queue_init()
{
    SEQQUEUE *queue=NULL;
    queue = (SEQQUEUE*)malloc(sizeof(SEQQUEUE));
    if(queue == NULL)
    {
        printf("malloc failed\n");
        return NULL;
    }
    queue->head = 0;
    queue->tail = 0;
    return queue;
}
 
/*进队列*/
int queue_push(SEQQUEUE *queue,DATATYPE_T  data)
{
    int ret = 0;
    ret = queue_full(queue);
    if(ret!=0)
    {
        printf("the queue is full\n");
        return -1;
    }
    queue->tail++;
    queue->data[queue->tail] = data;
    return 0;
}
 
/*出队列*/
DATATYPE_T *queue_pop(SEQQUEUE *queue)
{
    int ret = 0;
    ret = queue_empty(queue);
    if(ret!=0)
    {
        printf("the queue is empty\n");
        return NULL;
    }
    queue->head++;
    return &(queue->data[queue->head]);
}
 
/* 获取队列的第一个元素*/
DATATYPE_T *get_queue_first_element(SEQQUEUE *queue)
{
    int ret = 0;
    ret = queue_empty(queue);
    if(ret!=0)
    {
        printf("the queue is empty\n");
        return NULL;
    }
    return &(queue->data[queue->head]);
}
 
/*获取队列的长度*/
int get_queue_length(SEQQUEUE *queue)
{
    return ((queue->tail)-(queue->head));
}
 
/*释放队列*/
void queue_free(SEQQUEUE *queue)
{
    if(queue!=NULL)
    {
        free(queue);
        queue = NULL;
    }
}
 
/*显示队列全部信息 */
int show_queue_info(SEQQUEUE *queue)
{
    int i = 0;
    for(i=queue->head+1;i<(queue->tail+1);i++)
    {
        printf("num:%d,time:%d\n",queue->data[i].number,queue->data[i].time);
    }
    return 0;
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
假设某银行有n个窗口对外接待客户,从早晨银行9点开门起到5点关门,不断有客户进入银行,由于每个窗口在某个时刻只能接待一个客户。因此在客户人数众多时需要在每个窗口前顺次排队,对于刚进银行的客户。如果某个窗口的业务员正空闲,则可上前输业务。反之,若个窗口均有客户所占,他便会排在为数最少的队伍后面。编制一个程序模拟银行的这种业务活动并计算一天中客户在银行的平均逗留时间。 首先从题目分析:N个窗口排队,首先就要建立N个队列来存储排队的用户信息 ,然后算出那个队列最短就用户就到那个队伍排队,同时通过随机生成他办理业务的时间和到来的时间,通过计算用户的到来时间和离开时间就可以计算出某个用户在银行的逗留时间 ;话不多说直接上代码。 下面是主函数,由用户输入银行上下班时间,计算营业多长时间Total_time,如何当前时间小于关门的时间,就一直进入customer_into();函数,用户不断的进来 #define FALSE 0 #define TRUE 1 #define QUEUE_SUM 4 //窗口的数量 int rand_business_time=0, rand_wait_time=0;//定义办理时间,等待时间变量 int Total_time=0,now_tim=0;//总时间,当前时间 int go_time[4] = {0,0,0,0};//定义数组存储每个窗口最后一位办理完业务的时间 int sum_nan[4] = {0,0,0,0};//定义数组存储每个窗口排队的人数 int Sign=TRUE; //是否关门标志位 float Sum_Wait_Time=0.0; //等待的总时间 float Sun_Nan=0.0; //总人数 int open_time;//开门时间 int off_time; //关门时间 int main() { Prompted(); printf("输入银行的24小时制营业时间:如营业时间为9:00--17:00,则应输入:9,17\n"); scanf("%d,%d", &open;_time,&off;_time); Total_time = (off_time - open_time) * 60;//计算银行总营业多少分钟 for (int i = 0; i now_time) { customer_into(); //客户进入函数 } printf("银行关门时间到不再接收客人\n\n"); for (int i = 0; i < QUEUE_SUM; i++) { DisposeQueue(&queue;[i],i);//输入在银行关门前还没有办理完业务的客户信息 } printf("平均时间为%.2f分钟",Sum_Wait_Time/Sun_Nan); /*通过各个客户的总等待时间总和/总人数算出逗留平均时间*/ _getch(); return 0; }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值