队列(纯C语言实现)
先进先出的线性表,从队尾rear进,从队头front出
1.队列的顺序存储结构及实现
补充:判断循环队列队满和队空的三种方法
由于队满和对空时都有front==rear
,所以需要另想方法来区分队满和队空
方法一:通过length的大小来判断
队空的条件为length==0
队满的条件为length==MAXSIZE
方法二:少用一个元素空间
队空的条件为front==rear
队满的条件为(rear+1)%MAXSIZE==front
方法三:设置一个标志变量flag
队空时flag==0
,队不空时flag==1
队空的条件为flag==0
队满的条件为front==rear&&flag==1
1.1 循环队列的存储结构
方法一:
typedef struct
{ElemType data[MAXSIZE];int front; //指向队头元素int rear; //指向队尾元素的下一个位置int length;
}SqQueue;
方法二:
typedef struct
{ElemType data[MAXSIZE];int front; int rear;
}SqQueue;
方法三:
typedef struct
{ElemType data[MAXSIZE];int front; int rear;int flag;
}SqQueue;
1.2 循环队列的基本操作
1.初始化InitQueue(Q)
方法一:
Status InitQueue(SqQueue *Q)
{Q->front=Q->rear=0;Q->length=0;return OK;
}
方法二:
Status InitQueue(SqQueue *Q)
{Q->front=Q->rear=0;return OK;
}
方法三:
Status InitQueue(SqQueue *Q)
{Q->front=Q->rear=0;Q->flag=0;return OK;
}
2.判断是否队空QueueEmpty(Q)
方法一:
Status QueueEmpty(SqQueue Q)
{if(Q.length==0) return TRUE;else return ERROR;
}
方法二:
Status QueueEmpty(SqQueue Q)
{ if(Q.front==Q.rear)return TRUE;elsereturn FALSE;
}
方法三:
Status QueueEmpty(SqQueue Q)
{ if(Q.flag==0)return TRUE;elsereturn FALSE;
}
3.销毁DestroyQueue(Q)
与清空ClearQueue(Q)相同
4.清空ClearQueue(Q)
方法一:
Status ClearQueue(SqQueue *Q)
{Q->front=Q->rear=Q->length=0;return OK;
}
方法二:
Status ClearQueue(SqQueue *Q)
{Q->front=Q->rear=0;return OK;
}
方法三:
Status ClearQueue(SqQueue *Q)
{Q->front=Q->rear=Q->flag=0;return OK;
}
5.求长度QueueLength(Q)
方法一:
int QueueLength(SqQueue Q)
{return Q.length;
}
方法二:
int QueueLength(SqQueue Q)
{return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}
方法三:(同方法二)
6.取队头元素GetHead(Q,e)
方法一:
Status GetHead(SqQueue Q,ElemType *e)
{if(Q.length==0)return ERROR;*e=Q.data[Q.front];return OK;
}
方法二:
Status GetHead(SqQueue Q,ElemType *e)
{if(Q.front==Q.rear)return ERROR;*e=Q.data[Q.front];return OK;
}
方法三:
Status GetHead(SqQueue Q,ElemType *e)
{if(Q.flag==0)return ERROR;*e=Q.data[Q.front];return OK;
}
7.入队列(插入队尾)EnQueue(Q,e)
方法一:
Status EnQueue(SqQueue *Q,ElemType e)
{if(Q->length==MAXSIZE)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE; //队尾指针指向下一个位置 Q->length++;return OK;
}
方法二:
Status EnQueue(SqQueue *Q,ElemType e)
{if ((Q->rear+1)%MAXSIZE == Q->front)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;return OK;
}
方法三:
Status EnQueue(SqQueue *Q,ElemType e)
{if(Q->front==Q->rear&&Q->flag==1)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;Q->flag=1;return OK;
}
8.出队列(删除队头)DeQueue(Q,e)
方法一:
Status DeQueue(SqQueue *Q,ElemType *e)
{if(Q->length==0) return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;Q->length--;return OK;
}
方法二:
Status DeQueue(SqQueue *Q,ElemType *e)
{if (Q->front == Q->rear)return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;return OK;
}
方法三:
Status DeQueue(SqQueue *Q,ElemType *e)
{if(Q->flag==0) return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;if(Q->front==Q->rear)Q->flag=0;return OK;
}
9.遍历QueueTraverse(Q)
Status visit(ElemType e)
{printf("%d ",e);return OK;
}
方法一:
Status QueueTraverse(SqQueue Q)
{int i,t;t=Q.front;for(i=0;i<Q.length;i++){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK;
}
方法二:
Status QueueTraverse(SqQueue Q)
{ int t;t=Q.front;while(t!=Q.rear){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK;
}
方法三:
Status QueueTraverse(SqQueue Q)
{ int i,t;t=Q.front;for(i=0;i<QueueLength(Q);i++){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK;
}
1.3 循环队列的综合实例
#include<stdio.h>#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 15typedef int Status;
typedef int ElemType;typedef struct
{ElemType data[MAXSIZE];int front; int rear;int flag; //队空时flag==0,队不空时flag==1
}SqQueue;Status InitQueue(SqQueue *Q)
{Q->front=Q->rear=0;Q->flag=0;return OK;
}int QueueLength(SqQueue Q)
{return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}Status visit(ElemType e)
{printf("%d ",e);return OK;
}Status QueueTraverse(SqQueue Q)
{ int i,t;t=Q.front;for(i=0;i<QueueLength(Q);i++){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK;
}Status EnQueue(SqQueue *Q,ElemType e)
{if(Q->front==Q->rear&&Q->flag==1)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;Q->flag=1;return OK;
}Status DeQueue(SqQueue *Q,ElemType *e)
{if(Q->flag==0) return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;if(Q->front==Q->rear)Q->flag=0;return OK;
}Status GetHead(SqQueue Q,ElemType *e)
{if(Q.flag==0)return ERROR;*e=Q.data[Q.front];return OK;
}Status QueueEmpty(SqQueue Q)
{ if(Q.flag==0)return TRUE;elsereturn FALSE;
}void menu()
{printf(" ********循环队列功能菜单********** \n");printf(" 1.初始化 ");printf("2.输出栈中各结点的值\n");printf(" 3.入队列 ");printf("4.出队列\n");printf(" 5.查看队头元素 ");printf("6.是否为空队列\n");printf(" 7.退出\n");
}int main()
{int i,n;int choice=0;SqQueue Q;ElemType e;InitQueue(&Q);menu();while(choice!=7){printf("请选择功能:\n");scanf("%d",&choice);switch(choice){case 1: if(InitQueue(&Q)){printf("初始化成功\n");}break;case 2:if(QueueEmpty(Q)){printf("队列为空!\n");}else{printf("遍历结果如下:\n");QueueTraverse(Q); }break;case 3:printf("请输入你要入队列的元素:\n"); scanf("%d",&e);if(EnQueue(&Q,e)){printf("入队列成功\n");}else{printf("队列已满,入队列失败\n");}break;case 4:if(DeQueue(&Q,&e)){printf("出队列成功,出队列元素为%d\n",e);}else{printf("队列为空,出队列失败\n");}break;case 5:if(GetHead(Q,&e))printf("队头元素是%d\n",e);elseprintf("该队列为空,无队头元素\n");break;case 6:if(QueueEmpty(Q)){printf("当前队列为空\n");}else{printf("当前队列不为空\n");}break;case 7:printf("******************END**********************\n");break;}}return 0;
}
2.队列的链式存储结构及实现
1.1 链队列的存储结构
有头结点的链队列
typedef struct QNode
{ElemType data;struct QNode *next;
}QNode;
typedef struct
{QNode *front,*rear;int length;
}LinkQueue;
1.2 链队列的基本操作
1.初始化InitQueue(Q)
生成一个空的链队列,front和rear都指向头结点
Status InitQueue(LinkQueue *Q)
{Q->front=Q->rear=(QNode*)malloc(sizeof(QNode)); //生成头结点if(!Q->front)exit(OVERFLOW);Q->front->next=NULL;Q->length=0;return OK;
}
2.判断是否队空QueueEmpty(Q)
Status QueueEmpty(LinkQueue Q)
{ if(Q.length==0) //判断条件也可以是Q.front==Q.rearreturn TRUE;elsereturn FALSE;
}
3.销毁DestroyQueue(Q)
销毁包括头结点在内的所有节点,使front和rear指向NULL
Status DestroyQueue(LinkQueue *Q)
{while(Q->front){Q->rear=Q->front->next;free(Q->front);Q->front=Q->rear;}Q->length=0;return OK;
}
4.清空ClearQueue(Q)
只保留一个头结点
Status ClearQueue(LinkQueue *Q)
{QNode *p,*q;Q->rear=Q->front;p=Q->front->next;Q->front->next=NULL;while(p){q=p;p=p->next;free(q);}Q->length=0;return OK;
}
5.求长度QueueLength(Q)
int QueueLength(LinkQueue Q)
{return Q.length;
}
6.取队头元素GetHead(Q,e)
Status GetHead(LinkQueue Q,ElemType *e)
{ QNode *p;if(Q.length==0) //判断条件也可以是Q.front==Q.rearreturn ERROR;p=Q.front->next;*e=p->data;return OK;
}
7.入队列(插入队尾)EnQueue(Q,e)
Status EnQueue(LinkQueue *Q,ElemType e)
{QNode *p=(QNode *)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e;Q->rear->next=p;p->next=NULL;Q->rear=p; //修改rear指针 Q->length++;return OK;
}
8.出队列(删除队头)DeQueue(Q,e)
Status DeQueue(LinkQueue *Q,ElemType *e)
{QNode *p;if(Q->length==0) //判断条件也可以是Q->front==Q->rearreturn ERROR;p=Q->front->next;*e=p->data;Q->front->next=p->next;if(Q->rear==p) //若p结点是队尾元素,则删除p后变为空队列,需将rear指向头结点 Q->rear=Q->front;free(p);Q->length--;return OK;
}
9.遍历QueueTraverse(Q)
Status visit(ElemType e)
{printf("%d ",e);return OK;
}
Status QueueTraverse(LinkQueue Q)
{QNode *p;p=Q.front->next;while(p){visit(p->data);p=p->next;}printf("\n");return OK;
}
1.3 链队列的综合实例
#include<stdio.h>
#include<stdlib.h>#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2 typedef int Status;
typedef int ElemType;//先定义结点
typedef struct QNode
{ElemType data;struct QNode *next;
}QNode;
//再定义链队列
typedef struct
{QNode *front,*rear;int length;
}LinkQueue;//初始化:生成一个空的链队列,front和rear都指向头结点
Status InitQueue(LinkQueue *Q)
{Q->front=Q->rear=(QNode*)malloc(sizeof(QNode)); //生成头结点if(!Q->front)exit(OVERFLOW);Q->front->next=NULL;Q->length=0;return OK;
}//清空:只保留一个头结点,其余结点都释放
Status ClearQueue(LinkQueue *Q)
{QNode *p,*q;Q->rear=Q->front;p=Q->front->next;Q->front->next=NULL;while(p){q=p;p=p->next;free(q);}Q->length=0;return OK;
}//输出元素
Status visit(ElemType e)
{printf("%d ",e);return OK;
}
//遍历输出
Status QueueTraverse(LinkQueue Q)
{QNode *p;p=Q.front->next;while(p){visit(p->data);p=p->next;}printf("\n");return OK;
}Status QueueEmpty(LinkQueue Q)
{ if(Q.length==0) //判断条件也可以是Q.front==Q.rearreturn TRUE;elsereturn FALSE;
}Status GetHead(LinkQueue Q,ElemType *e)
{ QNode *p;if(Q.length==0) //判断条件也可以是Q.front==Q.rearreturn ERROR;p=Q.front->next;*e=p->data;return OK;
}Status EnQueue(LinkQueue *Q,ElemType e)
{QNode *p=(QNode *)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e;Q->rear->next=p;p->next=NULL;Q->rear=p; //修改rear指针 Q->length++;return OK;
}Status DeQueue(LinkQueue *Q,ElemType *e)
{QNode *p;if(Q->length==0) //判断条件也可以是Q->front==Q->rearreturn ERROR;p=Q->front->next;*e=p->data;Q->front->next=p->next;if(Q->rear==p) //若p结点是队尾元素,则删除p后变为空队列,需将rear指向头结点 Q->rear=Q->front;free(p);Q->length--;return OK;
}void menu()
{printf(" ********链队列功能菜单******** \n");printf(" 1.初始化 ");printf("2.输出栈中各结点的值\n");printf(" 3.入队列 ");printf("4.出队列\n");printf(" 5.查看队头元素 ");printf("6.是否为空队列\n");printf(" 7.退出\n");
}int main()
{int choice=0;LinkQueue Q;ElemType e;InitQueue(&Q);menu();while(choice!=7){printf("请选择功能:\n");scanf("%d",&choice);switch(choice){case 1: if(ClearQueue(&Q)){printf("初始化成功\n");}break;case 2:if(QueueEmpty(Q)){printf("队列为空!\n");}else{printf("遍历结果如下:\n");QueueTraverse(Q); }break;case 3:printf("请输入你要入队列的元素:\n"); scanf("%d",&e);if(EnQueue(&Q,e)){printf("入队列成功\n");}break;case 4:if(DeQueue(&Q,&e)){printf("出队列成功,出队列元素为%d\n",e);}else{printf("队列为空,出队列失败\n");}break;case 5:if(GetHead(Q,&e))printf("队头元素是%d\n",e);elseprintf("该队列为空,无队头元素\n");break;case 6:if(QueueEmpty(Q)){printf("当前队列为空\n");}else{printf("当前队列不为空\n");}break;case 7:printf("******************END**********************\n");break;}}return 0;
}
队列(纯C语言实现)相关推荐
- 刁肥宅手笔:纯C语言实现链式队列的相关操作
先上图,以图服人: 图一 程序运行截图1 图二 程序运行截图2 上代码: 头文件LinkQueue.h: /*LinkQueue.h*/#ifndef LINKQUEUE_H_INCLUDED #de ...
- linux下c语言聊天室程序,纯C语言Socket实现聊天室
最近在学习嵌入式开发,练习C语言小项目,基本是参考别人的代码,做了些修改实现了聊天室,纯C语言编写. 想直接看源码的跳到最后. 一.练习内容 socket通信流程 管道的使用 epoll的使用 首先要 ...
- 使用纯C语言开始win32 sdk编程
使用纯C语言开始win32 sdk编程 今天开始加强用c语言进行win32 sdk编程的训练,不为别的,只为进一步加强自己对代码的感觉,加强快速写出正确代码的能力.因为c是如些地具有挑战性而灵活的语言 ...
- java的开源项目哪里找,我想参加开源项目的开发,请问在网上去哪找这样的项目? 纯C语言的(非C++或JAVA)...
我想参加开源项目的开发,请问在网上去哪找这样的项目? 纯C语言的(非C++或JAVA)以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起 ...
- 用ram实现寄存器堆_纯C语言实现bootloader
之前有用很少一部分汇编实现过bootloader,但经过后来慢慢改进,发现是可以用纯C语言实现嵌入式操作系统的引导. 下面是之前对不能完全使用C语言引导系统的几点说明: 1.C程序中所有的代码都是以函 ...
- 循环队列及C语言实现三
在之前的博客中给出了设计循环队列的思路以及源码,这些可都是经过我长期大数据测试的验证哦.当然,现在的很多开源项目和一些封装好的类或接口也都有类似的队列实现方法,之所以我还在使用自己写的这一套方法,主要 ...
- 循环队列及C语言实现二
在我的上一篇博文中已经讲到循环队列的特点作用以及C语言实现,当然实现和操作的方式比较简单,在实际项目应用中略显粗糙.因此,这一篇提供一个进阶篇的实现与操作接口.具体函数作用可以参见我的注释部分,使用的 ...
- 循环队列及C语言实现一
循环队列是为了充分利用内存,进行数据操作的一种基本算法.具体实现方式可划分为:链式队列和静态队列,这里所谓的静态是指在一片连续的内存区域进行数据操作.本文只讲述静态队列,也是最简单的实现方式,链式队列 ...
- 实现一个通用的生产者消费者队列(c语言版本)
背景:笔者之前一直从事嵌入式音视频相关的开发工作,对于音视频的数据的处理,生产者消费者队列必不可少,而如何实现一个高效稳定的生产者消费者队列则十分重要,不过按照笔者从业的经验,所看到的现象,不容乐观, ...
- 河南理工大学c语言报告封面,河南理工大学图书信息管理系统设计_纯c语言课程设计.doc...
河南理工大学图书信息管理系统设计_纯c语言课程设计 C语言课程设计报告 题 目:图书信息管理系统设计 河南理工大学计算机学院 目 录 第一章 题目与要求 1.1 问题提出1 1.2 本系统涉及的知识点 ...
最新文章
- python学精通要多久-学习Python零基础需要学多久?
- Code片段 : .properties属性文件操作工具类 JSON工具类
- java取number长度_Java中常用方法(NumberMath)
- Expected an Objective directive after @ 的解决办法
- C#接口中为什么不能像java那样使用static?
- 专题:数列信息传递问题转化为图论合点问题(ybtoj-数列询问+序列破解)
- 服务器启动时Webapp的web.xml中配置的加载顺序
- react父子组件通信案例
- 一文带你解读Volcano架构设计与原理
- matlab取矩阵实部和虚部,MATLAB中容易忽略却经常遇到的小技巧总结
- 参考ethtool写了个Linux设置、获取网卡模式的接口
- 什么是多态 重载 覆盖 继承 最好解释
- 烟台大学计算机学院学院,烟台大学计算机学院
- 13 登陆_《星球大战:弹珠台》中文版即将登陆Switch 12月13日正式发售
- Android Xml布局常见问题总结
- Atitit。sql2016标准化的规划方案 v3 q2a
- 阿里云ECS服务器Linux-ubuntu18环境搭建
- hdlbits刷题记录
- 快速由WP8升级到WP8.1
- java 点击叉号_怎么设置点击叉号然后内容消失,这是自己写的不知道哪里有问题?...