博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构-环形队列 C和C++的实现
阅读量:5136 次
发布时间:2019-06-13

本文共 8230 字,大约阅读时间需要 27 分钟。

队列:

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

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

结构如下图所示

环形队列:

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

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

 

C语言

程序清单:

本例中包含三个文件:

(插入图片)

Queue.h:

#ifndef _QUEUE_H#define _QUEUE_Htypedef 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
View Code

 

Queue.c:

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

 

main.c(用于测试):

#include 
#include
#include "Queue.h"int main(void){ int i; //queue(stack) Queue queue2[20]; //queue(heap) Queue *queue = (Queue*)malloc(sizeof(Queue)*20); //Queue Init Queue_Init(queue,20); Queue_Init(queue2,20); //queue1 printf("insert datas:(0-19)\r\n"); for(i=0;i<20;i++) { Queue_push(queue,i); } Queue_printf(queue); printf("delete datas(first 10):\r\n"); for(i=0;i<10;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=0;i<20;i++) { Queue_push(queue2,i*10); } Queue_printf(queue2); printf("delete datas(first 10):\r\n"); for(i=0;i<10;i++) { Queue_pop(queue2); } Queue_printf(queue2); //delete queue printf("\r\n"); printf("queue1 delete\r\n"); Queue_Delete(queue); free(queue); queue=0; printf("queue2 delete\r\n"); Queue_Delete(queue2); system("pause"); return 0;}
View Code

 

测试结果:

 

函数详解:

环形队列结构体:

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

必要参数:

  • 数据 *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 = 0;    queue->iTail=0;    queue->iHead=0;    queue->Datas = (Elem *)malloc(size*sizeof(Elem));    return 1;}

 

 

入队操作:

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

 

出队操作(分为两部分)

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

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

 

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

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

 

打印队列中的元素、

创建一个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=0;i
iLength;i++) { printf("%d ",queue->Datas[temp++%queue->iSize]); } printf("\r\n");}

 

C++语言

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

程序清单:

本部分包含三个文件:

(此处插入图)

 

转载于:https://www.cnblogs.com/HongYi-Liang/p/7244022.html

你可能感兴趣的文章
软件工程课堂作业
查看>>
OpenFire 的安装和配置
查看>>
web.config详解
查看>>
ZJOI2018游记Round1
查看>>
侧边栏广告和回到顶部
查看>>
杭电1159 Common Subsequence【最长公共子序列】
查看>>
UVa 11464 Even Parity
查看>>
第二周 9.5 --- 9.11
查看>>
LATEX双栏最后一页如何平衡两栏内容
查看>>
大神教你如何快速解决所有电脑的问题?
查看>>
SpringMVC运行原理
查看>>
一个彩色颗粒随鼠标移动的html5源码
查看>>
swun 1397 来电显示
查看>>
[NOI2010]能量采集
查看>>
css中的选择器
查看>>
Linux安装redis
查看>>
微软移动 Nokia Lumia SensorCore SDK 介绍及上手体验
查看>>
新浪微博——点击按钮自动加关注代码
查看>>
Eclipse plug-in startup
查看>>
springboot jpa 保存乱码
查看>>