队列:

含义:是一种先入先出(FIFO)的数据结构。

当我们把数据一个一个放入队列中。当我们需要用到这些数据时,每次都从队列的头部取出第一个数据进行处理。就像排队进场一样,先排队的人先进场。

结构如下图所示

环形队列:

含义:它是在写程序时候一种队列的特殊表达方式,把队列数据组中的最后一个元素和第一个元素相连构成环,所以称为环形队列。

优点:环形队列在C/C++编程中首元素出队后不需要把队列所有元素向前移动,而取代把把队首指针向后移动,由于其环形结构,在插入元素后队尾指针会循环到队首原来的位置。相对普通队列的出队操作减少了大量的运算量。

C语言

程序清单:

本例中包含三个文件:

(插入图片)

Queue.h:

#ifndef _QUEUE_H
#define _QUEUE_H
typedef unsigned char uint8_t;
typedef int Elem; typedef struct circlequeue
{
int iLength;
int iSize;
int iHead;
int iTail;
Elem *Datas;
}Queue; uint8_t Queue_Init(Queue* queue,int size);
uint8_t Queue_Delete(Queue *queue);
uint8_t isQueueEmpty(Queue *queue);
uint8_t isQueueFull(Queue *queue);
int Queue_size(Queue *queue);
uint8_t Queue_push(Queue *queue,Elem data);
Elem Queue_front(Queue *queue);
Elem Queue_back(Queue *queue);
uint8_t Queue_pop(Queue *queue);
void Queue_printf(Queue *queue); #endif

Queue.c:

#include <stdlib.h>
#include <stdio.h>
#include "Queue.h" /*******************************************************/
/*******************************************************/
/**********************创建队列*************************/
/*******************************************************/
/*******************************************************/
uint8_t Queue_Init(Queue* queue,int size)
{
queue->iSize = size;
queue->iLength = ;
queue->iTail=;
queue->iHead=;
queue->Datas = (Elem *)malloc(size*sizeof(Elem));
return ;
}
/*******************************************************/
/*******************************************************/
/**********************删除队列*************************/
/*******************************************************/
/*******************************************************/
uint8_t Queue_Delete(Queue *queue)
{
free(queue->Datas);
return ;
}
/*******************************************************/
/*******************************************************/
/*********************队头队尾操作**********************/
/*******************************************************/
/*******************************************************/
static void QueueTailAdd(Queue *queue)
{
queue->iTail++;
queue->iTail = queue->iTail % queue->iSize;
}
static void QueueHeadAdd(Queue *queue)
{
queue->iHead ++;
queue->iHead = queue->iHead % queue->iSize;
}
/*******************************************************/
/*******************************************************/
/***********************队列判空************************/
/*******************************************************/
/*******************************************************/
uint8_t isQueueEmpty(Queue *queue)
{
if(queue->iLength == )
{
return ;
}
return ;
}
/*******************************************************/
/*******************************************************/
/***********************队列判满************************/
/*******************************************************/
/*******************************************************/
uint8_t isQueueFull(Queue *queue)
{
if(queue->iLength>=queue->iSize)
{
return ;
}
return ;
}
/*******************************************************/
/*******************************************************/
/*******************返回队列现有长度********************/
/*******************************************************/
/*******************************************************/
int Queue_size(Queue *queue)
{
return queue->iLength;
}
/*******************************************************/
/*******************************************************/
/********************往队尾放入元素*********************/
/*******************************************************/
/*******************************************************/
uint8_t Queue_push(Queue *queue,Elem data)
{
if(isQueueFull(queue))
{
return ;
} queue->Datas[queue->iTail] = data;
QueueTailAdd(queue);
queue->iLength++;
return ;
}
/*******************************************************/
/*******************************************************/
/************获取队头第一个元素(不删除)***************/
/*******************************************************/
/*******************************************************/
Elem Queue_front(Queue *queue)
{
if(isQueueEmpty(queue))
{
return ;
} return queue->Datas[queue->iHead];
}
Elem Queue_back(Queue *queue)
{
if(isQueueEmpty (queue))
{
return ;
}
return queue->Datas[queue->iTail];
}
/*******************************************************/
/*******************************************************/
/******************删除队列第一个元素*******************/
/*******************************************************/
/*******************************************************/
uint8_t Queue_pop(Queue *queue)
{
if(isQueueEmpty(queue))
{
return ;//queue empty
} QueueHeadAdd(queue);
queue->iLength--;
return ;
}
/*******************************************************/
/*******************************************************/
/*****************打印队列中的全部元素******************/
/*******************************************************/
/*******************************************************/
void Queue_printf(Queue *queue)
{
int i;
int temp = queue->iHead;
printf("queue datas:\r\n");
for(i=;i<queue->iLength;i++)
{
printf("%d ",queue->Datas[temp++%queue->iSize]);
}
printf("\r\n");
}

main.c(用于测试):

#include <stdlib.h>
#include <stdio.h>
#include "Queue.h" int main(void)
{
int i;
//queue(stack)
Queue queue2[];
//queue(heap)
Queue *queue = (Queue*)malloc(sizeof(Queue)*);
//Queue Init
Queue_Init(queue,);
Queue_Init(queue2,); //queue1
printf("insert datas:(0-19)\r\n");
for(i=;i<;i++)
{
Queue_push(queue,i);
} Queue_printf(queue); printf("delete datas(first 10):\r\n");
for(i=;i<;i++)
{
Queue_pop(queue);
} Queue_printf(queue); printf("first data:%d\r\n",Queue_front(queue)); printf("queuesize = %d\r\n",Queue_size(queue)); //queue2
printf("\r\n");
printf("insert datas to queue2:(0-190,10interval)\r\n");
for(i=;i<;i++)
{
Queue_push(queue2,i*);
} Queue_printf(queue2); printf("delete datas(first 10):\r\n");
for(i=;i<;i++)
{
Queue_pop(queue2);
} Queue_printf(queue2); //delete queue
printf("\r\n");
printf("queue1 delete\r\n");
Queue_Delete(queue);
free(queue);
queue=; printf("queue2 delete\r\n");
Queue_Delete(queue2); system("pause");
return ;
}

测试结果:

函数详解:

环形队列结构体:

在循环队列中,有以下参数

必要参数:

  • 数据 *Datas;
  • 对尾索引 iTail;
  • 队头索引 iHead;

可选参数:

  • 队列总大小 iSize;//队列最大存放量,防止不当操作造成堆栈溢出
  • 队列现在的长度 iLength;//储存现在的长度减少运算量(不定义此参数可以通过队头队尾索引差值计算长度)
typedef struct circlequeue
{
int iLength;
int iSize;
int iHead;
int iTail;
Elem *Datas;
}Queue;

创建队列:

  1. 设置队列的最大长度;
  2. 把队列中的其他参数清零;
  3. 为队列的数据区域申请内存;
uint8_t  Queue_Init(Queue* queue,int size)
{
queue->iSize = size;
queue->iLength = ;
queue->iTail=;
queue->iHead=;
queue->Datas = (Elem *)malloc(size*sizeof(Elem));
return ;
}

入队操作:

  1. 判断队列是否已满,满则无法插入,返回0插入失败;
  2. 往队尾插入数据
  3. 队尾索引增加
  4. 队列长度增加
uint8_t Queue_push(Queue *queue,Elem data)
{
if(isQueueFull(queue))
{
return ;
} queue->Datas[queue->iTail] = data;
QueueTailAdd(queue);
queue->iLength++;
return ;
}

出队操作(分为两部分)

出队细分一、获取队头元素但不删除

  1. 判断队列是否为空,空则获取失败返回0;
  2. 返回队列中队头索引指向元素
Elem Queue_front(Queue *queue)
{
if(isQueueEmpty(queue))
{
return ;
} return queue->Datas[queue->iHead];
}

出队细分二、删除队头的元素但不返回其值

  1. 判断队列是否为空,空则删除失败;
  2. 增加队头索引;
  3. 减少队列长度;
uint8_t Queue_pop(Queue *queue)
{
if(isQueueEmpty(queue))
{
return ;//queue empty
} QueueHeadAdd(queue);
queue->iLength--;
return ;
}

打印队列中的元素、

创建一个temp等于队头索引,后边打印中使用;

循环打印iLength(队列长度)个数据;

从队头(temp)指向的元素开始打印,每打印一个数据后temp++(指向下一个元素),(特别说明:temp%queue->iSize取余数,当temp索引超过最大长度时自动返回数组头开始打印,temp++%queue->iSize相当于两步1、temp%queue->iSize 2、temp++)

void Queue_printf(Queue *queue)
{
int i;
int temp = queue->iHead;
printf("queue datas:\r\n");
for(i=;i<queue->iLength;i++)
{
printf("%d ",queue->Datas[temp++%queue->iSize]);
}
printf("\r\n");
}

C++语言

C++中思路和C基本类似,这里就不在赘述。上程序:

程序清单:

本部分包含三个文件:

(此处插入图)

数据结构-环形队列 C和C++的实现的更多相关文章

  1. 【数据结构】C++语言无锁环形队列的实现

    无锁环形队列 1.Ring_Queue在payload前加入一个头,来表示当前节点的状态 2.当前节点的状态包括可以读.可以写.正在读.正在写 3.当读完成后将节点状态改为可以写,当写完成后将节点状态 ...

  2. 【数据结构】C++语言环形队列的实现

    队列--先进先出 队列的一个缺点--出队后的内存空间浪费了,不能二次利用 环形队列--解决以上缺点的队列,用过的内存空间可以重复利用 github: https://github.com/HITFis ...

  3. 【转】C#环形队列

    概述 看了一个数据结构的教程,是用C++写的,可自己C#还是一个菜鸟,更别说C++了,但还是大胆尝试用C#将其中的环形队列的实现写出来,先上代码: 1 public class MyQueue< ...

  4. C#实现环形队列

    概述 看了一个数据结构的教程,是用C++写的,可自己C#还是一个菜鸟,更别说C++了,但还是大胆尝试用C#将其中的环形队列的实现写出来,先上代码: public class MyQueue<T& ...

  5. <2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现

    栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO).栈能够将递归问题转化为非递归问题,这是它的一个重要特性.除了FILO.FIFO这样的最普遍存取方式外, ...

  6. 图解Java数据结构之队列

    本篇文章,将对队列进行一个深入的解析. 使用场景 队列在日常生活中十分常见,例如:银行排队办理业务.食堂排队打饭等等,这些都是队列的应用.那么队列有什么特点呢? 我们知道排队的原则就是先来后到,排在前 ...

  7. 【C/C++】缓冲区设计--环形队列

    原文链接:http://blog.csdn.net/billow_zhang/article/details/4420789 在程序的两个模块间进行通讯的时候,缓冲区成为一个经常使用的机制. 如上图, ...

  8. Java 单向队列及环形队列

    队列的特点 1.可以使用数组和链表两种方式来实现. 2.遵循先入先出(FIFO)的规则,即先进入的数据先出. 3.属于有序列表. 图解实现过程: ​ 1.定义一个固定长度的数组,长度为maxSize. ...

  9. 高性能环形队列框架 Disruptor 核心概念

    高性能环形队列框架 Disruptor Disruptor 是英国外汇交易公司LMAX开发的一款高吞吐低延迟内存队列框架,其充分考虑了底层CPU等运行模式来进行数据结构设计 (mechanical s ...

随机推荐

  1. USB的四种传输类型与端点

    1.事务 在介绍USB传输类型之前,请允许我先简答介绍一下USB事务. 事务一般由令牌包.数据包(可选).握手包组成. 令牌包:用来启动一个事务,总是由主机发送. 数据包:可以从主机到设备,也可以由设 ...

  2. 基于.NET CORE微服务框架 -谈谈surging的服务容错降级

    一.前言 对于不久开源的surging受到不少.net同学的青睐,也受到.net core学习小组的关注,邀请加入.NET China Foundation以方便国内.net core开源项目的推广, ...

  3. 认识cpu、核与线程

    作为一个后台开发人员,我想有必要了解这些基础知识.如果本文有不严谨或者疏忽的地方,请指正. cpu与核心 物理核 物理核数量=cpu数(机子上装的cpu的数量)*每个cpu的核心数 虚拟核 所谓的4核 ...

  4. ionic2+Angular ionScroll页面滑动监听

    第一:需要在组件中引入相关模块: 第二:如果只是监听页面滑动,只需要标注@ViewChild(Content) content: Content;就可以了. 附加:如果要监听页面的某个元素,并对其进行 ...

  5. (转)Java线程:新特征-线程池

    Java线程:新特征-线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利 ...

  6. amd和cmd区别

    作者:玉伯 链接:https://www.zhihu.com/question/20351507/answer/14859415 来源:知乎 著作权归作者所有,转载请联系作者获得授权. AMD 是 R ...

  7. zabbix_server---微信报警

    (1)         企业应用-创建应用 1.除了对个人添加微信报警之外,还可以添加不同管理组,接受同一个应用推送的消息, 成员账号,组织部门ID,应用Agent ID,CorpID和Secret, ...

  8. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及abp封装的Javascript函数库

    经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这里算是前面几节的一个初次试水. 首先我们数据库已经有的相应的数据. 模型和DTO已经建好,所以我们直接在服务 ...

  9. 最短路和次短路问题,dijkstra算法

    /*  *题目大意:  *在一个有向图中,求从s到t两个点之间的最短路和比最短路长1的次短路的条数之和;  *  *算法思想:  *用A*求第K短路,目测会超时,直接在dijkstra算法上求次短路; ...

  10. 前端开发工具Brackets介绍,安装及安装Emme插件时踩过的坑

    对于前端开发的园友来说有可能IDE工具有很多,层次不穷,还有每个人的喜好及习惯也不一样,因为我是一名后端开发的.Net程序员,但是大家都知道,现在都提倡什么全栈工程师,所以也得会点前端开发,所以我对于 ...