队列的特征:

特殊的线性表,先进先出(FIFO)

(1)数据:对于非空的队列,表头没有直接前驱,表尾没有直接后继,其他有且仅有一个直接前驱和一个直接后继。

(2)操作:只允许在表尾插入数据,在表头删除数据

顺序队列:

定义:

它是顺序表的一种,具有顺序表同样的数据结构,由数组定义,配合用数组下标表示对头指针和队尾指针完成各种操作。

表示:

#define MAXSIZE 10
typedef int datatype;/* 定义队列中数据元素的数据类型*/typedef struct seq{datatype data[MAXSIZE]; /* 用数组作为队列的存储空间*/int front;//front:始终存放队头位置的前一个下标;int rear; //rear:始终存放队尾元素的下标}seqqueue,*seqqueue_p; /* 顺序队列类型定义*/

存在的问题:

1、入队和出队:随着入队、出队操作的进行,整个队列会整体向后移动,这样就出现了下图的现象:队尾指针虽然已经移到了最后,而队列却未真满的“假溢出”现象,使得队列的空间没有得到有

效的利用。

改进前:

改进方法:改进为一个循环队列

改进后:

2、根据问题1的改进后,可得到一个循环队列,如下图所示,这时候我们初始化队列时就不应该将front和rear初始化为-1了(当然也不是不可以,只是根据循环队列更好理解),那么我们就应该把front和rear初始化为MAXSIZE-1;这时候问题又来了,当我们一直入队操作,当满了之后,front和rear又相等了,这就不能判断队列到底为空还是为满(因为rear==front这个条件也为空队列时的条件)。无法区别满对和空对

改进办法:少用(损失)一个空间,以队尾下标加1等于对头下标作为队满的标志。因此:当front=rear=MAXSIZE-1,表示循环队列为空;当front ==(rear+1)% MAXLEN,表示循环队列为满。

示例程序:用循环队列实现如下功能:用户从键盘输入整数,程序将其入队,用户输入字母,程序将对头元素出队,并在每次出队和入队之后打印队列元素。

代码实现:

seqqueue.c

#include "seqqueue.h"void create_seqqueue(seqqueue_p *seq)//创建一个队列
{(*seq) = (seqqueue_p)malloc(sizeof(seqqueue));if(NULL == (*seq)){perror("malloc");exit(-1);}// 断其臂,保其身,最后一个空。定义为满状态 (*seq)->front = (*seq)->rear = MAXSIZE-1;//初始化队头以及队尾指针return;
}
/* 判断队列是否已满*/
bool is_full_seqqueue(seqqueue_p seq)
{if( (seq->rear+1)%MAXSIZE == seq->front ){//已满 return true;} else{return false;}
}
/* 入队*/
bool in_seqqueue(seqqueue_p seq,datatype data)
{//判断队列是否已满if(is_full_seqqueue(seq)) {printf("队列已满\r\n");return false;}//入队seq->rear = (seq->rear+1) % MAXSIZE;seq->data[seq->rear] = data;return true;
} /* 判断队列是否为空*/
bool is_empty_seqqueue(seqqueue_p seq)
{if(seq->front == seq->rear){//已空 return true;}return false;
}
/* 出队*/
bool out_seqqueue(seqqueue_p seq,datatype* data)
{//判断队列是否为空if(is_empty_seqqueue(seq)){printf("队列已空\r\n");return false; }//出队seq->front = (seq->front+1)%MAXSIZE;*data = seq->data[seq->front];return true;
}
/* 打印*/
void show_seqqueue(seqqueue_p seq)
{int i;if(is_empty_seqqueue(seq)){/* 空不打印*/return;} /* 非空时,从对头打印数据到队尾*/for(i=(seq->front+1)%MAXSIZE ;i!=(seq->rear+1)%MAXSIZE; i=(i+1)%MAXSIZE) {printf("%d\r\n",seq->data[i]);}return;
}

seqqueue.h

#ifndef __SEQQUEUE_H__
#define __SEQQUEUE_H__#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdbool.h>#define MAXSIZE 10
typedef int datatype;/* 定义队列中数据元素的数据类型*/
typedef struct seq{datatype data[MAXSIZE]; /* 用数组作为队列的存储空间*/int front,rear;//front:指向队头位置的前一个元素的下标; rear;指向队尾元素的下标
}seqqueue,*seqqueue_p; /* 顺序队列类型定义*//**************************函数声明*******************************/
void create_seqqueue(seqqueue_p *seq);//创建一个队列
/* 入队*/
bool in_seqqueue(seqqueue_p seq,datatype data);
/* 出队*/
bool out_seqqueue(seqqueue_p seq,datatype* data);
/* 打印*/
void show_seqqueue(seqqueue_p seq);#endif

main.c

#include "seqqueue.h"int main()
{datatype data,t;seqqueue_p seq;int ret;create_seqqueue(&seq);//顺序队列初始化while(1){printf("请输入一个整数:");ret = scanf("%d",&data);//输入的是整数,入队 if(ret == 1){if(in_seqqueue(seq,data)){//插入元素成功 show_seqqueue(seq);}}//输入为字符时,出队 else{if(out_seqqueue(seq,&t)){printf("out:%d\r\n",t);show_seqqueue(seq);}//将前一个scanf输入的缓冲区通过循环全部清空while (getchar() != '\n');//表示只要字符不是回车就继续吃缓冲区字符}    } return 0;
}

链式队列

定义:

链式队列中每个元素定义成一个结点,含数据域与指针域(指向下一结点),并设头尾指针。用图表示就是。

规定:

front: 指向队头节点的前一个节点(头节点)的指针。

rear: 指向队尾节点的指针。

 表示:

typedef int datatype;    /* 定义链对列中数据元素的数据类型*/typedef struct node{datatype data;        /* 数据域*/struct node *next;    /* 链接指针域*/}linklist;                /* 链对元素类型定义*/typedef struct{linklist *front,*rear;       /* 链队列指针*/}linqueue,*linqueue_p;                /* 链队列类型定义*/

链队的基本操作

1. 链队的初始化

lsqueue *CreateLqueue()
{linkqueue * head = (linkqueue *)malloc(sizeof(linkqueue));if(head == NULL)return NULL;head->data = -1;head->next = NULL;lsqueue * lq = (lsqueue *)malloc(sizeof(lsqueue));if(lq == NULL)return NULL;lq->front = lq->rear = head;return lq;
}

2、入队

int EnLqueue(lsqueue *lq,data_t data)
{if(lq == NULL)return -1;linkqueue *new = (linkqueue *)malloc(sizeof(linkqueue));if(new == NULL)return -1;new->data = data;new->next = NULL;lq->rear->next = new;lq->rear = new;return 0;
}

3、出队

data_t DeLqueue(lsqueue *lq)
{if(lq == NULL || Lsqueue_is_Empty(lq))return -1;linkqueue *p = lq->front->next;data_t m = p->data;//如果p是最后一个有效结点 那么需要把rear 调整回跟 front 相等if(p->next != NULL){lq->front->next = p->next;free(p);p = NULL;}else{lq->front->next = p->next;lq->rear = lq->front;free(p);p = NULL;}return m;}

4、判断队列是否为空

int Lsqueue_is_Empty(lsqueue *lq)
{if(lq == NULL)return -1;return lq->front == lq->rear;
}

5、打印队列

int PrintLinkqueue(lsqueue *lq)
{if(lq == NULL)return -1;linkqueue *p = lq->front->next;while(p != NULL){printf(" %d ",p->data);p = p->next;}printf("\n");
}

C语言数据结构-队列相关推荐

  1. 舞伴配对问题c语言实训报告,C语言数据结构队列实现舞伴匹配(数据结构第二次实验)...

    C语言实验作业 题目如下: 课程名称:数据结构 实验目的: 1.掌握队列的定义及实现: 2.掌握利用队列的基本操作. 实验要求: 1.    使用链式结构完成队列的各种基本操作: 2.    补充完善 ...

  2. GO语言-数据结构-队列

    目录 1.队列的顺序存储结构 1.1 队列顺序存储结构-结构体定义 1.2 队列顺序存储结构--初始化队列 1.3 队列顺序存储结构-入队 1.4 队列顺序存储结构-出队 1.5 完整代码 2.循环队 ...

  3. c语言数据结构之队列

    前言 不同于栈,队列是一个先进先出的数据结构,规定数据节点从队列尾插入,从队列头取出,禁止对头尾两端以外的数据进行操作.队列可以分为顺序队列和循环队列. C语言数据结构之单链表 C语言数据结构之双向链 ...

  4. c语言编程队列题,数据结构C语言编程 队列.doc

    数据结构C语言编程 队列 #include #include #define MAXQSIZE 10 typedef struct { int *base; //存储空间的起始地址,即数组的首地址,即 ...

  5. C语言数据结构【手抄版】第三章 栈和队列

    注意:文中彩色代码均在Visual Studio 2022编译器中编写,本文为C语言数据结构手抄版,文中有部分改动,非原创. 目录 注意:文中彩色代码均在Visual Studio 2022编译器中编 ...

  6. 数据结构——队列的C语言代码实现

    系列文章目录 数据结构--顺序表的C语言代码实现 数据结构--八种链表的C语言代码实现 数据结构--栈的C语言代码实现 数据结构--队列的C语言代码实现 数据结构--堆的C语言代码实现 文章目录 系列 ...

  7. 一些可运行的C语言数据结构代码

    网上有很多C语言数据结构代码:有的不能运行:下面是一些能运行的,和运行截图:备用一下: 1 队列 #include<stdio.h> #include<stdlib.h>#de ...

  8. C语言数据结构【手抄版】第五章 树和二叉树【上篇】

    注意:文中彩色代码均在Visual Studio 2022编译器中编写,本文为C语言数据结构手抄版,文中有部分改动,非原创. 目录 5.1.树的基本概念和术语 1.树的定义 2.树的表示法 3.基本术 ...

  9. C语言数据结构之二叉树的层次建树及遍历方法(前序,中序,后序,层次遍历)

    C语言数据结构之二叉树的层次建树及遍历方法(前序,中序,后序,层次遍历) tips:前些天学习了C语言数据结构链表,栈,队列.今天来学习一下C语言数据结构之二叉树的各种操作. 注意:二叉树的层次建树是 ...

  10. Go语言-数据结构与算法

    go语言之专业数据结构与算法 3.golang实现数组结构 code\ArrayList\ArrayList.go package ArrayListimport ("errors" ...

最新文章

  1. 查询提升200倍,ClickHouse你值得拥有!
  2. 手机html检测蓝牙打印机,打印机手机确认.html
  3. 24、Power Query-数学运算的应用(统计男女人数)
  4. Cisco系列网络设备测试命令大全
  5. oracle 日期转换成毫秒数,ORACLE:毫秒与日期的相互转换,获取某天的信息
  6. jsdroid 教程_南方Cass专题,全系列教程+插件汇总打包
  7. 微软windows10易升_Windows10把软件设置为始终以管理员身份运行(适用于单个软件)...
  8. OpenCV 人脸识别、图片相似度检测
  9. 有T2 表中的数据,求出NAME中每组累加 / 每组总数的比例大于0.6 的id 和name
  10. 解决redis 6379本地可以访问,外网却不行
  11. 关于原生解析的简单使用
  12. jupyter lab 插件安装及必备插件
  13. Netapp大概简介(一)
  14. 我的24H(外企工作日/周末)
  15. 手机QQ轻聊版,3.2.0升级3.3.1区别
  16. leetcode系列-111.二叉树的最小深度
  17. 公司注册资本认缴是什么意思?
  18. 【ResNet】肺炎CT影像识别
  19. JiggleBone基础
  20. MATLAB算法实战应用案例精讲-【智能优化算法】海洋捕食者算法(MPA)(补充篇) (附实战应用案例)

热门文章

  1. redis 实践笔记和源码分析
  2. opengl 库函数 glew glfw glad glut gl glu freeglut
  3. 在线数字转大写金额工具
  4. java 特殊字符分割_java字符串分割处理split及特殊符号
  5. 华为云学院新春大礼包:场景化微认证上新了!
  6. pg 备份恢复(四)—— 逻辑备份(dump与copy导入导出)
  7. Excel在统计分析中的应用—第十一章—相关分析-多元相关-偏相关系数
  8. excel小写转大写公式_不要眨眼!中英文、大小写转换,一秒就搞定!
  9. MFC编程 小说分割器
  10. 前端,后端,前台,后台到底应该怎么理解。