c语言建立队列

  • 一、顺序队列
    • 队列的顺序存储结构
    • 顺序队列的讨论
      • "下溢"现象
      • "真上溢"现象
    • "假上溢"现象
  • 二、如何解决"假上溢"问题
  • 三、循环队列
    • 循环队列说明
    • 循环队列的实现方法
      • 1、设置一个标记以区别队列是空还是满
      • 2、使用一个计数器记录队列中元素的总数
      • 3、保留对空条件,修改队满条件(常用)
    • 循化队列的存储结构定义
    • 初始化队列
    • 设置标志
      • 入队操作
      • 出队操作
    • 设置计数器方法
      • 入队操作
      • 出队操作
    • 方法三
      • 入队操作
      • 出队操作
    • 其余操作
  • 四、链式队列
    • 说明
    • 链式存储结构
    • 入队操作
    • 出队操作
    • 其余操作

一、顺序队列

因为顺序队列实现比较简单,所以就来谈谈实现的思路和一些注意事项。

队列的顺序存储结构

队列的顺序存储结构称为顺序队列,是利用一组连续的存储单元(一维数组)依次存放从队首到队尾的各个元素。由于随着人队和出队操作的变化,队列的队头和队尾的位置是变动的,所以应设置两个整型变量front和rear,分别指示队头和队尾在数组空间中的位置,通常称from为队头指针,rear为队尾指针,它们的初值在队列初始化时均应置为0,并约定在非空队列里,队首指针from始终指向队头元素,队尾指针rear始终指向队尾元素的下一个位置。

一般在顺序存储结构中,如果用双指针来进行操作,一般移动(或者先移动的都是指向最后边元素的下一个位置,目的是方便操作。

顺序队列的讨论

"下溢"现象

当队列为空,即font == rear,若作出出队列的操作产生的溢出现象,称为下溢

"真上溢"现象

rear == MAXQSIZE时,若作出入队列的操作产生的溢出现象,称为真上溢

"假上溢"现象

有真必有假嘛,假上溢指的是随着队列出队与入队的操作,头指针和尾指针只增加不减少,致使被删除元素的空间无法使用。因此,尽管队列中实际元素个数可能远远小于数组的大小,但可能尾指针可能已经超出数组的大小而无法进行入队操作,称为 "假上溢"现象.

二、如何解决"假上溢"问题

  • 当出现“假上溢”现象时,把所有的元素向低端移动,使得空位从高端区移向低端区,显然这种方法很浪费时间。
  • 将存储队列元素的一维数组首尾相接,形成一个环状。将这种形式表示的队列称为循环队列(Circular Queue)。
  • 采用链式队列。

三、循环队列

循环队列说明

在循化队列中进行出队、入队操作时,队头和对尾指针仍要加1。只不过当首、队尾指针指向数组上界( (MAXSIZE−1) )时,其加1操作的结果是指向数组的下界0,循环队列不会上溢。同样是约定在非空循环队列里,队首指针始终指向队头元素,队尾指针始终指向队尾元素的下一个位置。因此,真正实用的顺序队列是循环队列。

循环队列的实现方法

1、设置一个标记以区别队列是空还是满

设置标志flag,当Q.font ==Q.rear 且flag = 0时为队空,当Q.font ==Q.rear 且flag = 1时为队满。

2、使用一个计数器记录队列中元素的总数

设置一个变量count 来记录元素中的个数,当count ==0时为空,当count = =MAXQSIZE -1 时为满

3、保留对空条件,修改队满条件(常用)

少用一个元素的存储单元,未用单元不确定在哪一个位置,约定以“队列头指针在队列尾指针的下一位置(指环状的下一位置)上”作为队列呈“满”状态的标志。当存储循环队列的数组中只有一个空闲单元时,将循环队列视为队满,此时队尾指针和队头指针正好相差1,因此,队满条件为 。(Q⋅rear+1)%MAXQSIZE=Q.font。

循化队列的存储结构定义

# define MAXQSIZE 100 //定义队列最大容量(长度)
#define  QElemType int  //定义队列元素类型typedef struct {QElemType base[MAXQSIZE];int font, rear;
}SqQueue;

初始化队列

//初始化一个队列
void init(SqQueue& Q) {Q.font = 0;Q.rear = 0;
}

设置标志

入队操作

void push(SqQueue& Q, int val){if(flag == 1){printf("队列已满\n");return;}Q.base[Q.rear] = val; //添加到队列Q.rear++;if(Q.rear == MAXQSIZE)flag =1;
}

出队操作

//出队操作
int pop(SqQueue& Q) {if (!flag) {printf("队列为空\n");return 0;}int val = Q.base[Q.font];Q.font--;if(Q.font == Q.rear)flag = 0;return val;
}

设置计数器方法

入队操作

void push(SqQueue& Q, int val){if(count== MAXQSIZE){printf("队列已满\n");return;}Q.base[Q.rear] = val; //添加到队列Q.rear++;count ++;
}

出队操作

//出队操作
int pop(SqQueue& Q) {if (count == 0) {printf("队列为空\n");return 0;}int val = Q.base[Q.font];Q.font--;Q.count --;return val;
}

方法三

入队操作

// 入队列操作
void push(SqQueue& Q, int val) {if ((Q.rear + 1) % MAXQSIZE == Q.font) {printf("队列已满\n");return;}Q.base[Q.rear] = val; //添加到队列Q.rear = (Q.rear + 1) % MAXQSIZE; //队尾指针后移
}

出队操作

//出队操作
int pop(SqQueue& Q) {if (Q.font == Q.rear) {printf("队列为空\n");return 0;}int val = Q.base[Q.font];Q.font = (Q.font + 1) % MAXQSIZE;return val;
}

其余操作

//判断队列是否为空
int empty(SqQueue& Q) {if (Q.font == Q.rear)return 1;elsereturn 0;
}// 返回队列第一个元素int font(SqQueue& Q) {if (Q.font == Q.rear) {printf("队列为空\n");return 0;}return Q.base[Q.font];
}//返回队列中最后一个元素
int back(SqQueue& Q) {if (Q.font == Q.rear) {printf("队列为空\n");return 0;}return Q.base[Q.rear];
}//返回队列中元素个数
int size(SqQueue& Q) {return (Q.rear - Q.font + MAXQSIZE) % MAXQSIZE;
}//打印所以元素
void show(SqQueue Q) {while (!empty(Q)) {printf("%d ", pop(Q));}
}

四、链式队列

说明

链式队列与链式栈有一点不同是,链式栈是没有头结点的单链表,而链式队列是由头结点的,刚开始头指针与尾指针同时指向头节点。

区别于顺序存储的的双指针,尾指针是指向最后一个节点。

链式存储结构

#define QElemType int //元素类型typedef struct QNode { //队列的节点结构QElemType data;QNode* next;
}QNode, * Queueptr;typedef struct {Queueptr font; //队头指针Queueptr rear; //队尾指针
}LinkQueue;

入队操作

//入队操作
void push(LinkQueue& Q, QElemType val) {//创建新节点QNode* node;node = (QNode*)malloc(sizeof(QNode));if (!node) {printf("分配内存失败\n");return;}node->data = val; node->next = NULL; //形成新节点Q.rear->next = node;  //新节点插入队尾,Q.rear 相当于取得一个节点的地址Q.rear = node; //尾指针后移
}

出队操作

**注意:**当链式队列只有一个节点时,如果直接删除节点,因为尾指针指向该节点会导致失去尾指针,所以在删除前要先将头指针赋值给尾指针。

//出队操作
QElemType pop(LinkQueue& Q) {if (Q.font == Q.rear) {printf("队列为空\n");return 0;}QNode* p = Q.font->next;//取出队头指针QElemType val = p->data; //取出队头数据Q.font->next = p->next;//头指针后移if (p == Q.rear)Q.rear = Q.font; //防止只有一个节点时丢失尾指针free(p);//释放空间return val;
}

其余操作

//初始化队列
void init(LinkQueue& Q) {Q.font = Q.rear = (QNode*)malloc(sizeof(QNode));if (!Q.font) {printf("分配内存失败\n");return;}Q.font->next = NULL;
}
//判断队列是否为空
int empty(LinkQueue Q) {if (Q.font == Q.rear)return 1;elsereturn 0;
}//读取对头元素
QElemType font(LinkQueue& Q) {if (Q.font == Q.rear) {printf("队列为空\n");return -1;}QElemType val = Q.font->next->data;/*可以分解为* QNode *  p = Q.font->next;* QElemType val = p->data;*/return val;
}//读取队尾元素
QElemType back(LinkQueue& Q) {if (Q.font == Q.rear) {printf("队列为空\n");return -1;}QElemType val = Q.rear->data;return val;
}//销毁队列
void clear(LinkQueue& Q) {//引用型while (Q.font) {Q.rear = Q.font->next; //令尾指针指向队列的第一个元素free(Q.font); //在释放后可以不用将,指针置为空,不容易出现野指针Q.font = Q.rear; //第一次是头结点,后面的是元素节点}
}

c语言建立队列(顺序队列、循化队列和链式队列)相关推荐

  1. 数据结构 - 队列简介 及 1个简单的c语言链式队列代码实现

    1. 队列的定义 所谓队列(queue)就是一种能实现"先进先出"的一种线性存储结构. 跟栈有点类似,  例如栈只有1个出入口, 任何元素进入或者离开栈都必须经过同1个出入口(栈顶 ...

  2. 链式队列,队列篇(链式队列的出队入队操作)

    数据结构,队列篇(链式队列) 前言: 上一篇博主简单讲解了顺序队列和循环队列,今天讲解队列最后一篇链式队,链式队在数据结构中用到比较多,用来做一些排队的算法,还有链式队列是也是和链式栈一样采用链表的方 ...

  3. c语言队列(顺序队列,循环队列,链式队列)

    顺序队列 1.初始化: front=-1; rear=-1; 2.判空条件 font=rear; 3.队列已满条件 rear=max-1; 代码: #include<stdio.h> #i ...

  4. 数据结构——链式队列解析(C语言版)

    摘自:数据结构学习--链式队列解析(C语言版) 作者:正弦定理 发布时间:2020-11-26 21:07:08 网址:https://blog.csdn.net/chinesekobe/articl ...

  5. 【数据结构】链式队列的实现(C语言)

    队列的链式存储称为链式队列.链式队列就是一个特殊的单链表,对于这种特殊的单链表,它的插入和删除操作规定在单链表的不同端进行.链式队列的队首和队尾指针分别用front和rear表示. 链式队列要掌握以下 ...

  6. 数据结构之顺序队列和链式队列常用的一些操作

    顺序队列是队列的顺序存储结构,顺序队列实际上是运算受限的顺序表.和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素.由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示 ...

  7. 刁肥宅手笔:纯C语言实现链式队列的相关操作

    先上图,以图服人: 图一 程序运行截图1 图二 程序运行截图2 上代码: 头文件LinkQueue.h: /*LinkQueue.h*/#ifndef LINKQUEUE_H_INCLUDED #de ...

  8. c语言定义链式队列用菜单,数据结构之---C语言实现链式队列

    //链式队列的存储 //杨鑫 #include #include typedef int QElemType; //定义节点 typedef struct QNode { QElemType data ...

  9. (C语言版)栈和队列(一)——实现链式栈和链式队列的基本操作以及遇到的问题

    http://blog.csdn.net/fisherwan/article/details/20055179 首先要感谢这位大牛的一篇博客,地址如下:http://blog.csdn.net/hgu ...

最新文章

  1. Java快速创建大量对象_3分钟 快速理解JVM创建对象的步骤!
  2. 【环境】VS2013和MATLAB相互调用混合编程
  3. java实现图片对比功能_Java 照片对比功能的实现
  4. CSS基础(part8)--文本外观属性
  5. 拼图游戏C语言课设实验报告,C语言拼图游戏实验报告.doc
  6. linux迭代同步文件,Linux Shell——迭代循环
  7. 程序设计中为什么要解耦?
  8. 求不规则图形外接圆的算法 (附:三角形外接圆计算公式)
  9. 记一次苦逼的sql注入
  10. < 谈谈对 SPA(单页面应用)的理解 >
  11. dice系数 交叉熵_ACL2020 | 香侬科技提出用Dice Loss缓解数据集数据不平衡问题
  12. html5 application cache 空间限制,HTML5离线存储之Application Cache
  13. Excel-VBA操作文件四大方法
  14. Hbulider中,QQ分享到好友,总是提示,分享失败,请检查网络并重试
  15. 项目和项目管理基本概念
  16. STM32G431—ADC+E2PROM读写实验
  17. 创建算法交易机器人:用MQL4编写Expert Advisor的基础
  18. 《Python编程无师自通》第11章 练习
  19. 小尼机器人_机器人卖车?“小尼”已悄悄的来到了深圳
  20. 雪花飘落效果+雪花红梅 电视剧步步惊心插曲-刘诗诗

热门文章

  1. pycharm 导入或复制项目后run按钮灰色问题(显示pycharm add configuration)
  2. 初学__Python——Python中文支持、Python计算器
  3. SpringMVC(SSM)框架搭建JavaWeb项目时,前端页面文件上传,后台Java下载功能实现及相关问题记录说明
  4. MySQL的单表索引优化案例
  5. Make Even(800)
  6. Fall with Trees 二维平面直角坐标系-凸包-推公式
  7. python封装函数、实现将任意的对象序列化到磁盘上_Python系列之lambda、函数、序列化...
  8. ps -aux|grep 详细信息
  9. 虚拟机(VMware Workstation Pro)安装多台Linux
  10. yii2 mysql save_Yii2 开发 MySQL 数据备份功能