时间:2021-05-19
队列在编程语言中是如何定义的呢?小编与大家分享自己的经验。
队列的定义
队列是限制结点插入操作固定在一端进行,而结点的删除操作固定在另一端进行的线性表.
队列犹如一个两端开口的管道.允许插入的一端称为队头,允许删除的一端称为队尾.队头和队尾各用一个”指针”指示,称为队头指针和队尾指针.不含任何结点的队列称为”空队列”.队列的特点是结点在队列中的排队次序和出队次序按进队时间先后确定,即先进队者先出队.因此,队列又称先进先出表.简称FIFO(first in first out)表.
步骤
队列是用来存储暂未处理但需要按一定顺序处理的元素的一种数据结构。
队列是一种先进先出(First In First Out,FIFO)的线性表,特点是先进队的元素先出队。
队列只允许在表的一端进行插入,而在另一端删除元素。
队尾是队列中允许插入的一端;队首是队列中允许删除的一端。
一般用顺序表q[m]存储队列中的元素,m是队列能存储元素的最大数量。
front队首指针指向队首元素存储的位置;rear队尾指针指向队尾元素的下一个位置。
顺序队列及其操作
队列的顺序存储结构
顺序存储结构存储的队列称为顺序队列.和顺序表一样,用一个一维数组存.对头在数组的低下标端,队尾设在高下表端.队头,队尾指针值是数组元素的下标.对头指针始终指向对头结点的前一个结点位置,初始值为0.队尾指针是指向队尾结点位置,初始值也为0.
队列初始条件:队头指针=队尾指针=0
队列满条件:队尾指针=m(设队列当前容量为m)
队列空条件:队头指针=队尾指针
在QueueCs.c文件中定义了结构
#define DT char#define M 100typedef struct { DT data[M]; int front,rear;}SEQUEUE;data[M]也为数组为队列,front为队头指针,rear为队尾指针.(注意:front和rear是整数类型,不是指针类型),当front=rear=0时,为初始队列.因为C语言中数组的第一个元素下标为0,而不是1;所以这里约定数组元素data[0]闲置不用.
顺序队列上的操作
(1)创建队列
初始化队列,队头指针和队尾指针=0.
在QueueControl.h写出方法声明
SEQUEUE initQueue();在QueueControl.c中实现此方法
#include "QueueControl.h"SEQUEUE initQueue(){ SEQUEUE Q; //1.初始化队列,队头指针=队尾指针=0 Q.front=Q.rear=0; return Q;}(2)插入
在QueueControl.h写出方法声明
SEQUEUE inQueue(SEQUEUE Q,DT x);在QueueControl.c中实现此方法
#include "QueueControl.h"SEQUEUE inQueue(SEQUEUE Q,DT x){ //1.判断队列是上溢,就是队尾指针是否等于最大申请的空间 if(Q.rear==M){ printf("Up Overflow\n"); }else{ //2.从队尾插入结点 Q.rear++; Q.data[Q.rear]=x; printf("in success\n"); } return Q;}(3)删除
在QueueControl.h写出方法声明
SEQUEUE outQueue(SEQUEUE Q);void printQueue(SEQUEUE Q);在QueueControl.c中实现此方法
#include "QueueControl.h"SEQUEUE outQueue(SEQUEUE Q){ //1.首先判断是否是空队列 if(Q.front==Q.rear){ printf("queue is empty\n"); }else{ //2.删除结点是从队头删除 Q.front++; printf("out success\n"); } return Q;}void printQueue(SEQUEUE Q){ //1.从队头开始打印数据 SEQUEUE temp=Q; printf("queue={"); while (temp.front<temp.rear) { temp.front++; if(temp.front==Q.front+1){ printf("%c",temp.data[temp.front]); }else{ printf(",%c",temp.data[temp.front]); } } printf("}\n");}在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "QueueControl.h"int main(int argc, const char * argv[]) { //初始化顺序队列 SEQUEUE queue=initQueue(); printQueue(queue); //插入 queue=inQueue(queue, 'a'); queue=inQueue(queue, 'b'); queue=inQueue(queue, 'c'); queue=inQueue(queue, 'd'); printQueue(queue); //删除 queue=outQueue(queue); printQueue(queue); return 0;}打印结果:
queue={}
in success
in success
in success
in success
queue={a,b,c,d}
out success
queue={b,c,d}
Program ended with exit code: 0
从插入队列和删除队列操作的打印结果来看,队列的特点确实是:先进先出.
循环队列及其操作
循环队列的存储结构
根据顺序队列的操作和叙述可以看出,队尾指针=m表示队满,不能再插入结点了,当队头指针等于队尾指针表示对空.但是当队尾指针和队尾指针都等于m的时候,那么此时表示对空,那么也不能插入了其他的结点,但是此时0-m之间的结点已经空闲,这样许多空闲的结点不能被利用,浪费存储空间.
循环队列是把顺序队列的头尾相接形成一个圆环.逻辑上吧1号结点作为m号结点的后继结点处理.
循环队列初始条件:队头指针=队尾指针=0
循环队列队满条件:MOD(队尾指针+1,m)=队头指针
循环队列空条件:队头指针=队尾指针
队头指针推进计算:队头指针=MOD(队头指针+1,m)
队尾指针推进计算:队尾指针=MOD(队尾指针+1,m)
在QueueCycleCs.c文件中定义了结构
#define CDT char#define CM 5typedef struct { CDT data[CM]; int front,rear;}SECYCLEQUEUE;循环队列上的操作
(1)创建循环队列
初始化队列,队头指针和队尾指针=0.
在QueueCycyleControl.h写出方法声明
#include "QueueCycleCs.c"SECYCLEQUEUE initCycleQueue();在QueueCycyleControl.c中实现此方法
#include "QueueCycleControl.h"SECYCLEQUEUE initCycleQueue(){ SECYCLEQUEUE Q; //队头指针=队尾指针=0; Q.front=Q.rear=0; return Q;}(2)插入
在QueueCycyleControl.h写出方法声明
#include "QueueCycleCs.c"SECYCLEQUEUE inCycleQueue(SECYCLEQUEUE Q,char x);在QueueCycyleControl.c中实现此方法
#include "QueueCycleControl.h"SECYCLEQUEUE inCycleQueue(SECYCLEQUEUE Q,CDT x){ //1.判断循环队列是否已经满了,MOD(队尾指针+1,m)=队头指针 if((Q.rear+1)%CM==Q.front){ printf("queue is full!\n"); }else{ //2.在队尾插入,计算队尾指针的 Q.rear=(Q.rear+1)%CM; //3.设置插入结点的值数值 Q.data[Q.rear]=x; printf("in Cycle queue Success!\n"); } return Q;}(3)删除
在QueueCycyleControl.h写出方法声明
#include "QueueCycleCs.c"SECYCLEQUEUE outCycleQueue(SECYCLEQUEUE Q);void printCycleQueue(SECYCLEQUEUE Q);在QueueCycyleControl.c中实现此方法
#include "QueueCycleControl.h"SECYCLEQUEUE outCycleQueue(SECYCLEQUEUE Q){ //1.判断循环队列是否是空 if(Q.front==Q.rear){ printf("Cycle queue is Empty!\n"); }else{ //2.删除结点从队头删除,计算队头指针:队头指针=MOD(队头指针+1,m) Q.front=(Q.front+1)%CM; printf("out cycle queue success!\n"); } return Q;}void printCycleQueue(SECYCLEQUEUE Q){ //M=5; //1.从队头开始打印数据 SECYCLEQUEUE temp=Q; printf("queue={"); //2.判断的条件是,队头指针!=队尾指针 while (temp.front!=temp.rear) { temp.front=(temp.front+1)%CM; if(temp.front==((Q.front+1)%CM)){ printf("%c",temp.data[temp.front]); }else{ printf(",%c",temp.data[temp.front]); } } printf("}\n");}在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "QueueCycleControl.h"int main(int argc, const char * argv[]) { //创建循环队列 SECYCLEQUEUE CQ=initCycleQueue(); //插入数据5个结点,但是最大是5,一个空闲,最后一个添加不进去, CQ=inCycleQueue(CQ, 'a'); CQ=inCycleQueue(CQ, 'b'); CQ=inCycleQueue(CQ, 'c'); CQ=inCycleQueue(CQ, 'd'); CQ=inCycleQueue(CQ, 'e'); printCycleQueue(CQ); //删除节点-三个结点 CQ=outCycleQueue(CQ); CQ=outCycleQueue(CQ); CQ=outCycleQueue(CQ); printCycleQueue(CQ); //插入-两个结点 CQ=inCycleQueue(CQ, 'e'); CQ=inCycleQueue(CQ, 'f'); printCycleQueue(CQ); //删除节点--删除四个结点,现在此时是三个结点,最后一个删除不了 CQ=outCycleQueue(CQ); CQ=outCycleQueue(CQ); CQ=outCycleQueue(CQ); CQ=outCycleQueue(CQ); printCycleQueue(CQ); return 0;}打印结果:
in Cycle queue Success!
in Cycle queue Success!
in Cycle queue Success!
in Cycle queue Success!
queue is full!
queue={a,b,c,d}
out cycle queue success!
out cycle queue success!
out cycle queue success!
queue={d}
in Cycle queue Success!
in Cycle queue Success!
queue={d,e,f}
out cycle queue success!
out cycle queue success!
out cycle queue success!
Cycle queue is Empty!
queue={}
Program ended with exit code: 0
链队列及其操作
队列的链存储结构
链存储结构存储的队列称为链队列.队头指针指向链队列的头结点,头结点的指针域若为空,则为空队列;若不为空,则为指向队首结点的指针.
链队列设有一个队头指针,其值指向队列的头结点.也是唯一地标示一个链队.设置一个队尾指针方便插入结点.队头指针和队尾指针都是指针型变量.
链队列没有容量的限制,所以在可用的存储空间范围内,一般不会出现上溢问题,也不存在如顺序队列的假溢出问题.
在QueueLinkCs.c中定义了结构
#define LDT char//结点类型typedef struct llnode{ LDT data; struct llnode *next;}LINKNODE;//链队列结构typedef struct{ LINKNODE *front,*rear;}LINKQUEUE;链队列上的操作
(1)创建链队列
在QueueLinkControl.h写出方法声明
#include <stdio.h>#include "QueueLinkCs.c"LINKQUEUE * initLinkQueue(LINKQUEUE *LQ);在QueueLinkControl.c中实现此方法
#include "QueueLinkControl.h"#include <stdlib.h>LINKQUEUE *initLinkQueue(LINKQUEUE *LQ){ //设置队头指针 LQ->front=(LINKNODE *)malloc(sizeof(LINKNODE)); LQ->front->data='#';//设置队头指针,也是头结点的指针域 LQ->front->next=NULL; //初始条件:队头指针和队尾指针一致 LQ->rear=LQ->front; return LQ;}(2)插入
在QueueLinkControl.h写出方法声明
LINKQUEUE * inLinkQueue(LINKQUEUE *LQ,LDT x);在QueueLinkControl.c中实现此方法
(3)删除
在QueueLinkControl.h写出方法声明
LINKQUEUE *outLinkQueue(LINKQUEUE *LQ);void printLinkQueue(LINKQUEUE *LQ);在QueueLinkControl.c中实现此方法
#include "QueueLinkControl.h"#include <stdlib.h>LINKQUEUE *outLinkQueue(LINKQUEUE *LQ){ if(LQ==NULL || LQ->rear==LQ->front){ printf("LQ is empty!\n"); return LQ; } //1.获取首结点 LINKNODE *frontNextNode; frontNextNode=LQ->front->next; //2.将首节点的next指针域的值存储头结点的next域 LQ->front->next=frontNextNode->next; //3.如果队尾结点等于首节点的next指针域的值,那么表示是空栈,根据空链队列的结构,还需修改队尾指针,使指向头结点. if(LQ->rear==frontNextNode){ LQ->rear=LQ->front; } //4.释放删除的结点 free(frontNextNode); printf("out link queue success!\n"); return LQ;}void printLinkQueue(LINKQUEUE *Q){ //实例化一个LQ,为了不改变原来链队Q LINKQUEUE *LQ; LQ=(LINKQUEUE *)malloc(sizeof(LINKQUEUE)); LQ->front=Q->front; LQ->rear=Q->rear; printf("queue={"); //1.判断不是空链表 if(LQ!=NULL && LQ->rear!=LQ->front){ int flag=0; do{ //2.输出数据 if(flag==0){ printf("%c",LQ->front->data); flag=1; }else{ printf(",%c",LQ->front->data); } //3.链头指针向后移动 LQ->front=LQ->front->next; }while (LQ->front!=LQ->rear) ; printf(",%c",LQ->front->data); } printf("}\n");}在main.c中的main方法(int main(int argc, const char * argv[]) {})调用此方法,并且进行判断
#include "QueueLinkControl.h"int main(int argc, const char * argv[]) { //创建链队列 LINKQUEUE *LQ=(LINKQUEUE *)malloc(sizeof(LINKQUEUE)); LQ=initLinkQueue(LQ); //向链队插入结点 LQ=inLinkQueue(LQ,'a'); LQ=inLinkQueue(LQ,'b'); LQ=inLinkQueue(LQ,'c'); LQ=inLinkQueue(LQ,'d'); printLinkQueue(LQ); //删除结点--从队头 LQ=outLinkQueue(LQ); LQ=outLinkQueue(LQ); printLinkQueue(LQ); return 0;}打印结果:
in link queue success!
in link queue success!
in link queue success!
in link queue success!
queue={#,a,b,c,d}
out link queue success!
out link queue success!
queue={#,c,d}
Program ended with exit code: 0
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
在之前我们详细介绍了C语言中如何使用宏定义(#ifndef/#define/#endif)来有效避免头文件被重复#include,此方式在C++多文件编程中也很
在C语言中“char”是声明一个字符类型的指针,定义数据类型,char可以定义字符有变量、数组、指针。 C语言是一门面向过程的计算机编程语言,与C++、Jav
c语言中规定函数的返回值的类型是由在定义该函数时所指定的函数类型所决定的。 C语言是一门面向过程的计算机编程语言,与C++、Java等面向对象编程语言有所不同
编程语言int是整型变量的意思。 在C/C++编程语言中,int表示整型变量,是一种数据类型,用于定义一个整型变量,在不同编译环境有不同的大小,不同编译运行环
c语言void和int的区别: 1、指代不同。int:是一种数据类型,在编程语言中,是用于定义整数类型变量的标识符。void:无类型。常用在程序编写中对定义函