c语言建立队列(顺序队列、循化队列和链式队列)
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个简单的c语言链式队列代码实现
1. 队列的定义 所谓队列(queue)就是一种能实现"先进先出"的一种线性存储结构. 跟栈有点类似, 例如栈只有1个出入口, 任何元素进入或者离开栈都必须经过同1个出入口(栈顶 ...
- 链式队列,队列篇(链式队列的出队入队操作)
数据结构,队列篇(链式队列) 前言: 上一篇博主简单讲解了顺序队列和循环队列,今天讲解队列最后一篇链式队,链式队在数据结构中用到比较多,用来做一些排队的算法,还有链式队列是也是和链式栈一样采用链表的方 ...
- c语言队列(顺序队列,循环队列,链式队列)
顺序队列 1.初始化: front=-1; rear=-1; 2.判空条件 font=rear; 3.队列已满条件 rear=max-1; 代码: #include<stdio.h> #i ...
- 数据结构——链式队列解析(C语言版)
摘自:数据结构学习--链式队列解析(C语言版) 作者:正弦定理 发布时间:2020-11-26 21:07:08 网址:https://blog.csdn.net/chinesekobe/articl ...
- 【数据结构】链式队列的实现(C语言)
队列的链式存储称为链式队列.链式队列就是一个特殊的单链表,对于这种特殊的单链表,它的插入和删除操作规定在单链表的不同端进行.链式队列的队首和队尾指针分别用front和rear表示. 链式队列要掌握以下 ...
- 数据结构之顺序队列和链式队列常用的一些操作
顺序队列是队列的顺序存储结构,顺序队列实际上是运算受限的顺序表.和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素.由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示 ...
- 刁肥宅手笔:纯C语言实现链式队列的相关操作
先上图,以图服人: 图一 程序运行截图1 图二 程序运行截图2 上代码: 头文件LinkQueue.h: /*LinkQueue.h*/#ifndef LINKQUEUE_H_INCLUDED #de ...
- c语言定义链式队列用菜单,数据结构之---C语言实现链式队列
//链式队列的存储 //杨鑫 #include #include typedef int QElemType; //定义节点 typedef struct QNode { QElemType data ...
- (C语言版)栈和队列(一)——实现链式栈和链式队列的基本操作以及遇到的问题
http://blog.csdn.net/fisherwan/article/details/20055179 首先要感谢这位大牛的一篇博客,地址如下:http://blog.csdn.net/hgu ...
最新文章
- Java快速创建大量对象_3分钟 快速理解JVM创建对象的步骤!
- 【环境】VS2013和MATLAB相互调用混合编程
- java实现图片对比功能_Java 照片对比功能的实现
- CSS基础(part8)--文本外观属性
- 拼图游戏C语言课设实验报告,C语言拼图游戏实验报告.doc
- linux迭代同步文件,Linux Shell——迭代循环
- 程序设计中为什么要解耦?
- 求不规则图形外接圆的算法 (附:三角形外接圆计算公式)
- 记一次苦逼的sql注入
- < 谈谈对 SPA(单页面应用)的理解 >
- dice系数 交叉熵_ACL2020 | 香侬科技提出用Dice Loss缓解数据集数据不平衡问题
- html5 application cache 空间限制,HTML5离线存储之Application Cache
- Excel-VBA操作文件四大方法
- Hbulider中,QQ分享到好友,总是提示,分享失败,请检查网络并重试
- 项目和项目管理基本概念
- STM32G431—ADC+E2PROM读写实验
- 创建算法交易机器人:用MQL4编写Expert Advisor的基础
- 《Python编程无师自通》第11章 练习
- 小尼机器人_机器人卖车?“小尼”已悄悄的来到了深圳
- 雪花飘落效果+雪花红梅 电视剧步步惊心插曲-刘诗诗
热门文章
- pycharm 导入或复制项目后run按钮灰色问题(显示pycharm add configuration)
- 初学__Python——Python中文支持、Python计算器
- SpringMVC(SSM)框架搭建JavaWeb项目时,前端页面文件上传,后台Java下载功能实现及相关问题记录说明
- MySQL的单表索引优化案例
- Make Even(800)
- Fall with Trees 二维平面直角坐标系-凸包-推公式
- python封装函数、实现将任意的对象序列化到磁盘上_Python系列之lambda、函数、序列化...
- ps -aux|grep 详细信息
- 虚拟机(VMware Workstation Pro)安装多台Linux
- yii2 mysql save_Yii2 开发 MySQL 数据备份功能