C语言数据结构-队列
队列的特征:
特殊的线性表,先进先出(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语言数据结构-队列相关推荐
- 舞伴配对问题c语言实训报告,C语言数据结构队列实现舞伴匹配(数据结构第二次实验)...
C语言实验作业 题目如下: 课程名称:数据结构 实验目的: 1.掌握队列的定义及实现: 2.掌握利用队列的基本操作. 实验要求: 1. 使用链式结构完成队列的各种基本操作: 2. 补充完善 ...
- GO语言-数据结构-队列
目录 1.队列的顺序存储结构 1.1 队列顺序存储结构-结构体定义 1.2 队列顺序存储结构--初始化队列 1.3 队列顺序存储结构-入队 1.4 队列顺序存储结构-出队 1.5 完整代码 2.循环队 ...
- c语言数据结构之队列
前言 不同于栈,队列是一个先进先出的数据结构,规定数据节点从队列尾插入,从队列头取出,禁止对头尾两端以外的数据进行操作.队列可以分为顺序队列和循环队列. C语言数据结构之单链表 C语言数据结构之双向链 ...
- c语言编程队列题,数据结构C语言编程 队列.doc
数据结构C语言编程 队列 #include #include #define MAXQSIZE 10 typedef struct { int *base; //存储空间的起始地址,即数组的首地址,即 ...
- C语言数据结构【手抄版】第三章 栈和队列
注意:文中彩色代码均在Visual Studio 2022编译器中编写,本文为C语言数据结构手抄版,文中有部分改动,非原创. 目录 注意:文中彩色代码均在Visual Studio 2022编译器中编 ...
- 数据结构——队列的C语言代码实现
系列文章目录 数据结构--顺序表的C语言代码实现 数据结构--八种链表的C语言代码实现 数据结构--栈的C语言代码实现 数据结构--队列的C语言代码实现 数据结构--堆的C语言代码实现 文章目录 系列 ...
- 一些可运行的C语言数据结构代码
网上有很多C语言数据结构代码:有的不能运行:下面是一些能运行的,和运行截图:备用一下: 1 队列 #include<stdio.h> #include<stdlib.h>#de ...
- C语言数据结构【手抄版】第五章 树和二叉树【上篇】
注意:文中彩色代码均在Visual Studio 2022编译器中编写,本文为C语言数据结构手抄版,文中有部分改动,非原创. 目录 5.1.树的基本概念和术语 1.树的定义 2.树的表示法 3.基本术 ...
- C语言数据结构之二叉树的层次建树及遍历方法(前序,中序,后序,层次遍历)
C语言数据结构之二叉树的层次建树及遍历方法(前序,中序,后序,层次遍历) tips:前些天学习了C语言数据结构链表,栈,队列.今天来学习一下C语言数据结构之二叉树的各种操作. 注意:二叉树的层次建树是 ...
- Go语言-数据结构与算法
go语言之专业数据结构与算法 3.golang实现数组结构 code\ArrayList\ArrayList.go package ArrayListimport ("errors" ...
最新文章
- 查询提升200倍,ClickHouse你值得拥有!
- 手机html检测蓝牙打印机,打印机手机确认.html
- 24、Power Query-数学运算的应用(统计男女人数)
- Cisco系列网络设备测试命令大全
- oracle 日期转换成毫秒数,ORACLE:毫秒与日期的相互转换,获取某天的信息
- jsdroid 教程_南方Cass专题,全系列教程+插件汇总打包
- 微软windows10易升_Windows10把软件设置为始终以管理员身份运行(适用于单个软件)...
- OpenCV 人脸识别、图片相似度检测
- 有T2 表中的数据,求出NAME中每组累加 / 每组总数的比例大于0.6 的id 和name
- 解决redis 6379本地可以访问,外网却不行
- 关于原生解析的简单使用
- jupyter lab 插件安装及必备插件
- Netapp大概简介(一)
- 我的24H(外企工作日/周末)
- 手机QQ轻聊版,3.2.0升级3.3.1区别
- leetcode系列-111.二叉树的最小深度
- 公司注册资本认缴是什么意思?
- 【ResNet】肺炎CT影像识别
- JiggleBone基础
- MATLAB算法实战应用案例精讲-【智能优化算法】海洋捕食者算法(MPA)(补充篇) (附实战应用案例)