目录
队列的实现
文件名 | 功能描述 |
---|---|
LinkQueueAlgo.h | 链表队列算法实现,包含队列的基本操作接口(如初始化、清除、添加/删除等)。 |
LinkQueueDef.h | 定义队列数据结构(队列节点和队列指针)、公共类型和全局变量,为实现者提供接口。 |
pubuse.h | 提供公共使用功能,包含预处理宏、类型声明和一些常用函数定义,供其他模块引用。 |
LinkQueueUse.cpp | 应用层程序示例,使用自定义的 LinkQueue 类来实现队列的操作,通过交互式菜单演示队列的基本功能。 |
总结: 程序整体功能是使用链表实现的队列数据结构,并提供一系列操作(初始化、插入、删除、查看长度等),并通过LinkQueueUse.cpp
中的实际示例展示了队列在控制台应用中的操作和使用。
整体功能:此项目包含一系列文件,使用链表实现的LinkQueue
数据结构以及相关的头文件,提供基础操作接口,并通过LinkQueueUse.cpp
展示如何在实际应用中创建和使用这个队列。
项目获取
所有代码已经上传到CSDN,通过资源绑定功能,已经绑定本篇博客,有需要请自取,完整的VS2022项目,运行“数据结构-队列.sln”即可在vs2022中打开(一般来说,版本无限制)
在我上传时,设置了0积分,可以免费获取,但不保证后续积分要求会不会变化(但放心,不会变成付费或会员专享资源),不过,还请尽快保存!
具体实现解析
pubuse.h头文件
该程序文件 "pubuse.h" 包含多种头文件,定义了一个通用的数据结构和函数集。主要特性包括:
-
使用了 C++ 标准库,如
<string>
,<iostream>
等,以及 C 标准库<stdio.h>
,<stdlib.h>
, 和<conio.h>
。 -
定义了几个预处理器宏,如
TRUE
andFALSE
,用于表示布尔值;OK
和ERROR
作为函数返回值,表示操作成功或失败;还定义了一个Status
类型用于处理状态。 -
类似于 C 语言的
typedef
关键字,使用了typedef
把int
类型别名为Boolean
,可能用于简化代码或提供更易理解的名称。 -
注释表明,
OVERFLOW
常量未被定义,因为它的值在<math.h>
中已由 math 函数占用。
整体看,这似乎是一个包含基本数据类型和状态枚举的库头文件,为后续的程序开发提供基础数据结构和函数支持。
#include<string>
#include<ctype.h>
#include<malloc.h> /* malloc()等*/
#include<limits.h> /* INT_MAX 等*/
#include<stdio.h> /* EOF(=^Z 或F6),NULL */
#include<iostream>
#include<stdlib.h> /* atoi() */
#include<io.h> /* eof() */
#include<math.h>/* floor(),ceil(),abs() */
#include<process.h> /* exit() */
#include"conio.h"
#include <sstream>
using namespace std;
/* 函数结果状态代码*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//#define OVERFLOW -2 因为在math. h 中已定义OVERFLOW 的值为3,故去掉此行
typedef int Status; /* Status 是函数的类型,其值是函数结果状态代码,如OK 等*/
typedef int Boolean; /* Boolean 是布尔类型,其值是TRUE 或FALSE */
LinkQueueDef.h
文件
LinkQueueDef.h
文件定义了一个基于链接列表实现的队列数据结构。主要包含了以下内容:
-
QElemType:这是一个结构体别名,表示队列中的元素类型,这里定义为double类型的数值。
-
QNode:这是一个用于构建链表的结构体,包含两个成员:
- data: 存储 QElemType 类型的元素值。
- next: 指向下一个 QNode 的指针,用以构成链表。
-
QueuePtr:是 QNode 结构体的指针别名。
-
LinkQueue:这是全局队列结构体的定义,包含两个字段:
- front: 链表的前端指针,表示队列的第一个元素。
- rear: 链表的后端指针,表示队列的最后一个元素的下一个位置。
这个文件主要是为了在其他代码中使用这个自定义的队列数据结构,通过包含pubuse.h
(假设该头文件提供了相关的函数声明)可以操作这个队列,例如插入、删除等操作。
#include"pubuse.h"
typedef struct
{
double num;
}QElemType;
typedef struct QNode {
QElemType data;
struct QNode* next;
}QNode, * QueuePtr;
typedef struct {
QueuePtr front; // 队头指针
QueuePtr rear; // 队尾指针
}LinkQueue;
LinkQueueAlgo.h
头文件
这是一个名为LinkQueueAlgo.h
的头文件,它定义了一个基于链表实现的队列数据结构。该队列包含以下功能:
InitQueue
:初始化队列,创建一个新的链表节点指向前驱(front)和后继(rear),并将两者设置为NULL。DestroyQueue
:删除整个队列,通过遍历链表删除每个节点并释放内存。ClearQueue
:清空队列,与初始化类似,将队列的前后节点指向同一个新节点。QueueEmpty
:检查队列是否为空,即前驱和后继是否相等。QueueLength
:计算队列的长度,遍历链表长度。GetHead_Q
:获取队首元素,如果队列为空则返回错误。EnQueue
:入队操作,添加新的元素到队尾。DeQueue
:出队操作,删除队首元素,并将后继指向下个元素(删除前后节点的连接),若队列为空则返回错误。QueueTraverse
:实现队列的遍历,打印队列中的所有元素。
这些函数用于维护一个动态大小的链接队列,每个操作都考虑了队列的边界情况(如队列为空)。
#include"LinkQueueDef.h"
// 初始化队列
Status InitQueue(LinkQueue& Q) {
Q.front = Q.rear = new QNode;
Q.front->next = NULL;
return OK;
}
// 销毁队列
Status DestroyQueue(LinkQueue& Q) {
while (Q.front) {
QueuePtr p = Q.front->next;
delete Q.front;
Q.front = p;
}
return OK;
}
// 清空队列
Status ClearQueue(LinkQueue& Q) {
Q.front = Q.rear = new QNode;
Q.front->next = NULL;
return OK;
}
// 判断是否为空
bool QueueEmpty(LinkQueue Q) {
return Q.front == Q.rear;
}
// 求队列长度
int QueueLength(LinkQueue Q) {
int l = 0;
QueuePtr p = Q.front->next;
while (p) {
l++;
p = p->next;
}
return l;
}
// 取队头元素
Status GetHead_Q(LinkQueue Q, QElemType& e) {
if (QueueEmpty(Q)) return ERROR;
e = Q.front->next->data;
return OK;
}
// 入队
Status EnQueue(LinkQueue& Q, QElemType e) {
QueuePtr p = new QNode;
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
// 出队
Status DeQueue(LinkQueue& Q, QElemType& e) {
if (QueueEmpty(Q)) return ERROR; // 队列为空
QueuePtr p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if (Q.rear == p) Q.rear = Q.front;
delete p;
return OK;
}
// 遍历队列
Status QueueTraverse(LinkQueue Q) {
if (QueueEmpty(Q)) return ERROR;
QueuePtr p = Q.front->next;
while (p) {
cout << p->data.num << " ";
p = p->next;
}
cout << endl;
return OK;
}
LinkQueueUse.cpp
文件
LinkQueueUse.cpp
文件包含了一个名为 LinkQueue
的链表队列类的使用示例。该程序定义了一个菜单,用户可以选择执行以下操作:
1. 初始化队列(初始化操作)
2. 销毁队列(释放资源)
3. 清空队列
4. 检查队列是否为空
5. 获取队列长度
6. 从队头获取元素
7. 向队列中插入元素(字符串转换为double类型)
8. 从队列中删除元素
9. 遍历队列显示所有元素
10. 结束程序
main
函数处理用户输入的菜单选择,并调用相应的队列方法。文件中使用了自定义的队列算法(LinkQueueAlgo.h),这可能是一个链接列表实现的队列数据结构。整个程序流程控制在一个无限循环中,直到用户选择退出为止。
#include "LinkQueueAlgo.h"
void ShowMenu() {
cout << "========= 队列的实现及应用 =========" << endl;
cout << "1. 初始化队列(使用以下功能前,务必先初始化) " << endl;
cout << "2. 销毁队列" << endl;
cout << "3. 清空队列" << endl;
cout << "4. 判断是否为空队列" << endl;
cout << "5. 求队列长度" << endl;
cout << "6. 取队头元素" << endl;
cout << "7. 入队" << endl;
cout << "8. 出队" << endl;
cout << "9. 遍历队列" << endl;
cout << "0. 退出" << endl;
cout << "请输入你的选择:";
}
void ExitEnter() {
cout << "-------------------------------" << endl;
system("pause");
system("cls");
}
int main() {
LinkQueue Q;
QElemType e;
int numF = 9; //菜单选项数量
int choice;
do {
ShowMenu();
cin >> choice;
while (choice < 0 || choice>numF || cin.fail())
{
system("cls");
cin.clear();
cin.ignore();
ShowMenu();
cin >> choice;
}
switch (choice) {
case 1: {
// 初始化队列
system("cls");
if (InitQueue(Q)) cout << "队列初始化成功" << endl;
else cout << "初始化失败" << endl;
ExitEnter();
break;
}
case 2: {
// 销毁队列
system("cls");
if (DestroyQueue(Q)) cout << "销毁队列成功,请初始化队列后继续使用下面的功能" << endl;
else cout << "销毁队列失败" << endl;
ExitEnter();
break;
}
case 3: {
// 清空队列
system("cls");
if (ClearQueue(Q)) cout << "清空队列成功" << endl;
ExitEnter();
break;
}
case 4: {
// 判断是否为空队列
system("cls");
if (QueueEmpty(Q)) cout << "为空队列,可使用“入队”功能添加元素" << endl;
else cout << "队列不为空" << endl;
ExitEnter();
break;
}
case 5: {
// 求队列长度
system("cls");
int l = QueueLength(Q);
cout << "队列长度为:" << l << endl;
ExitEnter();
break;
}
case 6: {
// 取队头元素
system("cls");
if (GetHead_Q(Q, e)) {
cout << "取队头元素成功" << endl;
cout << "队头元素为:" << e.num << endl;
}
else cout << "取队头元素失败" << endl;
ExitEnter();
break;
}
case 7: {
// 入队
system("cls");
cin.ignore();
string s;
cout << "不断入队,入队元素用空格隔开,比如:1.2 3 2 8" << endl;
cout << "请输入需要入队的元素(double):";
getline(cin, s);
istringstream iss(s);
string s1;
double q;
while (iss >> s1) {
try {
q = stod(s1);
}
catch (const exception& e)
{
cout << s1 << ":非数字,跳过" << endl;
continue;
}
e.num = q;
if (EnQueue(Q, e)) cout << q << ":入队成功" << endl;
else cout << q << ":入队失败" << endl;
}
ExitEnter();
break;
}
case 8: {
// 出队
system("cls");
if (DeQueue(Q, e)) {
cout << "出队成功" << endl;
cout << "出队元素为:" << e.num << endl;
}
else cout << "出队失败" << endl;
ExitEnter();
break;
}
case 9: {
// 遍历队列
system("cls");
if (QueueTraverse(Q))cout << "\n遍历成功" << endl;
else cout << "遍历失败" << endl;
ExitEnter();
break;
}
case 0: {
cout << "-------------------------------" << endl;
cout << "感谢使用,再见!" << endl;
break;
}
default:
system("cls");
cout << "输入无效,请重新选择!" << endl;
break;
}
} while (choice != 0);
return 0;
}
结语
希望你能通过本篇博客,更好理解数据结构——队列。
最后,使用愉快!