数据结构实验三 链队
#include <iostream>
#include "stdio.h"
#include "stdlib.h"
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int QElemType;//因为要求是输入整数型数据元素
//00 数据结构定义
typedef struct QNode { // 结点QNode定义
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct { // 链队LinkQueue定义
QueuePtr front; // 队头指针
QueuePtr rear; // 队尾指针
} LinkQueue;
//01 初始化链队Q
Status InitLQueue(LinkQueue &Q)//Q为什么加&?Q是一个有两个指针域的结构体变量,有一个指针的值修改了,Q这个结构体变量就发生变化了。如果想让Q返回给主函数,这个子函数就要加&。
{
Q.rear=Q.front = new QNode;
Q.front->next = NULL;//头结点需要修改next为NULL;
return OK;0
}
//02 根据随机输入的队列长度和队列中整数型数据元素的值,创建一个非空链队列;
Status CreateLQueue(LinkQueue &Q)//即使已经初始化了,但每在队尾插入一个节点,Q的尾指针就要修改指向这个新加入的节点,故而Q发生了变化,想让主函数同时改变,则需加&。
{
if (!Q.front)
InitLQueue(Q);
int len, n;
QueuePtr p;
cout<< "请输入链队的长度(大于0的整数):";
cin >> len;
cout << "请输入" << len << "个整数:";
int i=0;
while (i<len)
{
cin >> n;
p = new QNode;
p->data = n;
p->next = NULL;
Q.rear->next = p;//首先,要把新结点链上去
Q.rear = p; //其次,修改尾指针rear指向这个新结点p
i++;
}
return OK;
}
//03 入队
Status EnQueue(LinkQueue &Q, QElemType e)
{
QueuePtr p;
if(Q.front)
{
p = new QNode;
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
else
{
cout << "链队不存在!" <<endl;
return ERROR;
}
}
//04 出队
Status DeQueue(LinkQueue &Q, QElemType &e)//出队是要删除对头元素,如果队中的节点大于等于2个,Q的f, r均不用修改,修改的头结点的next域,Q没发生变化,不用加&,但如果队中只有一个结点出队,则需修改Q.rear,Q发生变化了,故加&。同理e的值需要返回给主函数,故要加&。
{
if (Q.front == Q.rear)
{
printf("空链队\n");
return ERROR;
}
QueuePtr p;
p = Q.front->next; //p指向队头元素
e = p->data;
Q.front->next = p->next; //头结点的next指向p-next(p的后继结点);
if (Q.rear == p)
{
Q.rear = Q.front; //如果只有一个结点,尾指针也要修改;
}
delete p;
return OK;
}
//05 判定队列是否为空,若不空输出队头元素;注意与教材上的区别,两种不同的形式返回一个值
Status GetLQHead(LinkQueue Q, QElemType &e)//Q没变不加,e需要返回给主函数故加&。
{
if (Q.front != Q.rear)
{
e = Q.front->next->data;
return OK;
}
else
{
printf("当前链队为空,无头元素!\n");
return ERROR;
}
}
//06 输出链队当前元素个数;
Status GetLength(LinkQueue Q, int &len)//Q没变不加,len需要返回给主函数故加&。
{
len = 0;
if (Q.front != Q.rear)
{
QueuePtr p = Q.front->next;
while (p)
{
len++;
p = p->next;
}
}
return OK;
}
//07 输出队列中所有元素;
Status DisplayLQueue(LinkQueue Q)//Q没变不加&
{
if (Q.front == Q.rear)
{
printf("空链队\n");
return ERROR;
}
QueuePtr p=Q.front->next;
while (p)
{
cout << p->data << " ";
p = p->next;
}
return OK;
}
void main()
{
LinkQueue Q;
int i = InitLQueue(Q);//01初始化
printf("链队始化状态(OK-1;ERROR-0):%d\n", i);//测试链队初始化是否成功,OK-1
CreateLQueue(Q);//02链队的创建
printf("链队从对头到队尾的元素是:");
DisplayLQueue(Q);
printf("\n入队(只能在队尾),请输入一个整数:");
int x;
cin >> x;
EnQueue(Q, x);//03入队
DisplayLQueue(Q);
int y;
printf("\n出队(只能是队头)元素是:");
DeQueue(Q, y);//04出队,要删除队头元素
cout << y << endl;
cout << "出队后(Q少了一个元素),链队为:";
DisplayLQueue(Q);
int z;
printf("\n读取队头元素:");
GetLQHead(Q, z);//05读队头元素
cout << z << endl;
cout << "读队头元素后(Q不变),链队仍为:";
DisplayLQueue(Q);
int len;
GetLength(Q, len);//06当前链队长度
cout << "\n当前链队元素个数是:"<<len<<endl;
system("pause");//用于函数输出屏幕暂停,以便观察
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现