栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构 - 队列(顺序队列、单一数据类型)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构 - 队列(顺序队列、单一数据类型)

队列的概念

队列是一种特殊的线性表,数据从队尾进从对头出,遵循“先进先出”(First In First Out)的原则。
队列的实现方式很多,以C语言为例,队列可以是顺序队列(数据存储在连续的地址空间内,队列按照队列地址顺序排列),也可以是链式队列(地址在物理空间上不连续,通过链式指针访问下一个队列成员),本文介绍的就C语言实现的顺序队列。

顺序队列的思路

顺序队列通常采用数组的形式,在队列成员排在数组当中,有新的数据进来就排在数组后面,数据出去就从数组前面出去。但其中就会有个问题,如果要保证数组的第一位总是队头,那么出去一个数据就要把剩下的全部数据都要向前挪动一位,这将会带来很大的计算量,显然不是理想的做法。
这时候循环队列的思路就出来,可以假想这个数组是个循环的,首尾相接的,就不要一定要保证队头总是在数组的第一个位置,只需要增加个索引记住队头的位置,在出队的时候找到索引位置的数据,让其数据出队就行,然后更新索引到队列的下一个位置作为队头。同样增加个队尾索引,以方便入队。
在编程时候,就可以定义个队列控制体的结构体来记录队列的情况,定义个数组来存储队列。

C语言代码 头文件
#ifndef __queue_H
#define __queue_H

typedef int QUEUE_TYPE;

// 队列控制结构体。在队列应用中,定义一个QUEUE_CTRL Q,再定义一个队列BUF,同时对要对BUF及Q初始化
typedef struct 
{
	unsigned int	head;	// 队头 
	unsigned int	tail;	// 队尾 
	unsigned int	size;	// 队列大小
	unsigned char	state;	// 队列状态		1:队列中有数据   0:队列中无数据   
}QUEUE_CTRL;				// 队列控制结构体

void queue_init(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array, unsigned int queue_len);
unsigned char queue_empty(QUEUE_CTRL *queue_ctrl);
unsigned char queue_full(QUEUE_CTRL *queue_ctrl);
unsigned char queue_push(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array, QUEUE_TYPE data);
unsigned char queue_pop(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array, QUEUE_TYPE *data);
void queue_clean(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array);

#endif

可以看到,在队列控制结构体当中,定义了队头队尾的索引,以及队列的大小和队列状态。操作函数就包含有初始化、入队、出队、清空、检查是否满是否空。

源文件
#include "queue.h"
#include 
#include 


void queue_init(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array, unsigned int queue_len)
{
    unsigned int i = 0;
		
    queue_ctrl->tail = 0;
    queue_ctrl->head = 0;
    queue_ctrl->size = queue_len;
    queue_ctrl->state = 0;

    for (i = 0; i < queue_ctrl->size; i++)
    {
        queue_array[i] = 0;//初始化数据为0
    }
}


unsigned char queue_empty(QUEUE_CTRL *queue_ctrl)
{
    if (queue_ctrl->state == 0)
	{
		return 1;
	}
    else
	{
		return 0;
	}
}


unsigned char queue_full(QUEUE_CTRL *queue_ctrl)
{
    if (queue_ctrl->head == queue_ctrl->tail && queue_ctrl->state == 1)
	{
		return 1;
	}
    else
	{
		return 0;
	}
}


unsigned char queue_push(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array, QUEUE_TYPE data)
{
	if (queue_full(queue_ctrl))						// 队列满了
	{
		return 0;									// 操作失败
	}
	else											// 队列未满
	{
		queue_array[queue_ctrl->tail++] = data;		// 入队
		queue_ctrl->tail %= queue_ctrl->size;		// 入队计数器超最大值后,从0开始
		queue_ctrl->state = 1;						// 队列非空标志
		return 1;									// 操作成功
	}
}


unsigned char queue_pop(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array, QUEUE_TYPE *data)
{
    if(queue_empty(queue_ctrl))						// 队列无数据
    {
		return 0;									// 队列读取失败
    }
    else
    {
		*data = queue_array[queue_ctrl->head++];	// 读数据
		queue_ctrl->head %= queue_ctrl->size;		// 循环
		if(queue_ctrl->head == queue_ctrl->tail)	// 当取出数==放入数时,说明数据取出完了
		{
			queue_ctrl->state = 0;					// 队列状态改为无数据状态
		}
		return 1;									// 队列读取操作成功
    }
}


void queue_clean(QUEUE_CTRL *queue_ctrl, QUEUE_TYPE *queue_array)
{
    unsigned int i = 0;

    queue_ctrl->tail = 0;
    queue_ctrl->head = 0;
    queue_ctrl->state = 0;

	#if 1 // 可有可无
    for(i = 0; i < queue_ctrl->size; i++)
    {
        queue_array[i] = 0;
    }
	#endif
}


在代码中看到,真正实现了循环队列将数组首尾相连的是求余操作。
queue_ctrl->head %= queue_ctrl->size;
求余就让索引超过数组大小后回到第一个位置。

测试
#include 
#include "queue.h"

#define QUEUE_LEN	(10)

typedef struct 
{
	QUEUE_CTRL ctrl;
	QUEUE_TYPE buf[QUEUE_LEN];
}QUEUE;

int main()
{
	int i = 0;
	QUEUE queue;
	QUEUE_TYPE data = 0;

	queue_init(&queue.ctrl, queue.buf, QUEUE_LEN);

	for (i = 0; i < 11; i++)
	{
		data = i + 1;
		queue_push(&queue.ctrl, queue.buf, data);
	}
	
	for (i = 0; i < queue.ctrl.size; i++)
	{
		if (queue_pop(&queue.ctrl, queue.buf, &data) == 1)
		{
			printf("pop<%d> = %drn", i, data);
		}
	}

	getchar();
	return 0;
}

运行结果:

最后的最后,本人才疏学浅,此代码仅供参考交流,本人如有叙述错误,麻烦各位指正,有什么好的建议欢迎留言。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1026777.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号