C++实现循环队列和链式队列操作(实验5--作业)

循环队列 

一、主要功能

实现了顺序队列(SqQueue)的数据结构,并利用该队列实现了打印前n行杨辉三角的功能。

二、数据结构定义

  1. 定义了一些常量:
    • MAXSIZE表示队列的最大长度为 100。
    • OVERFLOw表示存储失败的错误码为 -2。
    • OKERROR分别表示操作成功和失败的状态码。
  2. 定义了数据类型:
    • Statusint类型,用于表示操作的状态。
    • QElemTypeint类型,代表队列中存储的数据类型。
  3. 定义了顺序队列结构体SqQueue
    • QElemType *base是指向存储队列元素的数组的指针。
    • int front表示队首指针。
    • int rear表示队尾指针。

三、函数功能

  1. InitQue函数:用于初始化顺序队列,为队列分配内存空间,并设置队首和队尾指针为 0。
  2. QueueLength函数:计算队列的长度,通过队尾指针减去队首指针再加上最大长度取余的方式来处理循环队列的情况。
  3. QueuePush函数:将元素入队,如果队列已满则返回错误状态。采用牺牲一个存储单元的方法判断队列是否已满,即当队尾指针的下一个位置等于队首指针时认为队列已满。
  4. QueuePop函数:将队首元素出队,如果队列为空则返回错误状态。出队后更新队首指针。
  5. GetQueueHead函数:获取队首元素的值,如果队列为空则不返回任何值。
  6. printPascalTriangle函数:打印前n行杨辉三角。使用顺序队列,通过不断出队、计算和入队的方式生成杨辉三角的每一行,同时打印前导空格以实现三角形的对齐。最后一行的最后一个元素总是 1,每次循环结束后将 1 入队为下一行做准备。

四、主函数流程

  1. 从用户输入获取要打印的杨辉三角的行数n
  2. 调用printPascalTriangle函数打印杨辉三角。
#include<bits/stdc++.h>//万能头文件
using namespace std;//命名空间

#define MAXSIZE 100 //最大长度
#define OVERFLOw -2
#define OK 1
#define QElemType int
#define ERROR 0

typedef int Status;
typedef struct {
	QElemType *base; //数组存放队列元素
	int front; //队首
	int rear;//队尾
}SqQueue;  

//队列的初始化
Status InitQue(SqQueue &Q){
	Q.base = new QElemType[MAXSIZE];//这么大的数组
	if(!Q.base) exit(OVERFLOW); 
	Q.front = Q.rear = 0; 
	return OK;
}
//求队列长度
int QueueLength (SqQueue &Q){ 
	// 返回队列 Q 的元素个数 
	return (Q.rear - Q.front+MAXSIZE)%MAXSIZE; 
}
//入队
Status QueuePush(SqQueue &Q,QElemType e){
	//判满
	//牺牲一个储存空间的方法
	if((Q.rear+1)%MAXSIZE == Q.front) 
		return ERROR;//队列满
	
	Q.base[Q.rear] = e;//索引偏移 存到rear处
	Q.rear = (Q.rear+1)%MAXSIZE;//循环队列 对MAXSIZE取余 防止下标越界
	return OK;
}
//出队
Status QueuePop(SqQueue &Q,QElemType &e){
	//判空
	if(Q.rear == Q.front) 
		return ERROR;//队列为空
	e = Q.base[Q.front];
	Q.front = (Q.front+1)%MAXSIZE;
	return OK;
}
//获取队首元素
QElemType GetQueueHead(SqQueue &Q){ 
	// 若队列不空,则返回队头元素的值
	if(Q.front != Q.rear) 
		return Q.base[Q.front]; 
} 


// 打印杨辉三角
void printPascalTriangle(int n){
	SqQueue Q;
	InitQue(Q);
	for(int i = 1; i <= n; i++){
		int size = QueueLength(Q); // 获取队列长度
		int prev = 0;
		for(int j = 0; j < n - i; j++) {
			cout << " "; // 打印前导空格
		}
		for(int j = 0; j < size; j++){
			QElemType curr;
			QueuePop(Q, curr);
			cout << prev + curr << " ";
			QueuePush(Q, prev + curr); // 将计算结果入队
			prev = curr;
		}
		cout << "1 " << endl; // 每行的最后一个元素是1
		QueuePush(Q, 1); // 将1入队,为下一行做准备
	}
}

int main(){
	int n;
	cin>>n;
	printPascalTriangle(n);
	return 0;
}

链式队列

一、主要功能

实现了链式队列(LinkQueue)的数据结构,并利用该队列实现了打印前n行杨辉三角的功能。

二、数据结构定义

  1. 定义了一些常量:
    • MAXSIZE表示队列的最大长度为 100(在链式队列中未实际用到)。
    • OVERFLOw表示存储失败的错误码为 -2。
    • OKERROR分别表示操作成功和失败的状态码。
  2. 定义了数据类型:
    • Statusint类型,用于表示操作的状态。
    • QElemTypeint类型,代表队列中存储的数据类型。
  3. 定义了链式队列的节点结构体QNode
    • QElemType data表示节点存储的数据。
    • struct QNode *next指向下一个节点的指针。
    • QueuePtr是指向QNode的指针类型别名。
  4. 定义了链式队列结构体LinkQueue
    • QueuePtr front表示队头指针,指向队列的头节点。
    • QueuePtr rear表示队尾指针,指向队列的最后一个节点。

三、函数功能

  1. InitQueue函数:用于初始化链式队列,创建一个头节点,并将队头指针和队尾指针都指向该头节点,同时将头节点的next指针置为NULL
  2. PushQueue函数:将元素入队,创建一个新节点,设置其数据域为给定元素,将新节点插入到队尾,更新队尾指针指向新节点。
  3. PopQueue函数:将队首元素出队,如果队列为空则返回错误状态。出队时,取出队首节点的数据,更新队头指针指向下一个节点,如果出队前队列只有一个元素,出队后需更新队尾指针使其与队头指针相同,表示队列为空。最后释放出队节点的内存空间。
  4. GetQueueHead函数:获取队首元素的值,如果队列为空则返回 0。
  5. QueueLength函数:计算链式队列的长度,通过遍历队列节点来统计节点个数。
  6. DestroyQueue函数:销毁链式队列,通过不断释放节点内存空间并更新队头指针的方式,将队列完全销毁。
  7. printPascalTriangle函数:打印前n行杨辉三角。使用链式队列,通过不断出队、计算和入队的方式生成杨辉三角的每一行,同时打印前导空格以实现三角形的对齐。最后一行的最后一个元素总是 1,每次循环结束后将 1 入队为下一行做准备。

四、主函数流程

  1. 从用户输入获取要打印的杨辉三角的行数n
  2. 调用printPascalTriangle函数打印杨辉三角。
#include<bits/stdc++.h>//万能头文件
using namespace std;//命名空间

#define MAXSIZE 100 //最大长度
#define OVERFLOw -2
#define OK 1
#define QElemType int
#define ERROR 0

typedef int Status;

typedef struct QNode {
	QElemType   data; 
	struct QNode  *next; 
} QNode,  *QueuePtr;   // 定义队列的结点 
typedef struct {
	QueuePtr   front;    // 队头指针 
	QueuePtr   rear;      // 队尾指针 
}LinkQueue; 

//队列的初始化
Status InitQueue (LinkQueue &Q ) {
	// 构造一个空队列 Q 
	Q.front = Q.rear = new QNode; 
	if(!Q.front)
		exit(OVERFLOw);//内存分配失败
	Q.front->next = NULL;
	return OK;
} 
//入队
Status PushQueue(LinkQueue &Q,QElemType e){
	QNode* p = new QNode;
	if(!p)exit(OVERFLOw);//内存分配失败
	p->data = e;
	p->next = NULL;
	//队尾的下一个指向p
	Q.rear->next = p;
	//队尾更新为p
	Q.rear = p;
	
	return OK;
}
//出队
Status PopQueue(LinkQueue &Q,QElemType &e){
	if(Q.front == Q.rear) return ERROR;//队列为空
	//front指向的是头节点 不是首元节点
	QNode* p = Q.front->next;
	e = p->data;//要删除的节点的data值
	Q.front->next = p->next;
	if(Q.rear == p)Q.rear = Q.front;//删除前只有一个元素 删除之后没有元素的情况 跟空对列一样了
	delete p;
	return OK;
	
}
QElemType GetQueueHead(LinkQueue Q){ 
	if (Q.front != Q.rear)	return Q.front->next->data;
	return 0;
}
//获取队列长度
int QueueLength(LinkQueue &Q){
	int len = 0;
	QNode *p = Q.front->next;
	while(p){
		len++;
		p=p->next;
	}
	return len;
}

//销毁队列
Status DestroyQueue(LinkQueue &Q){
	while(Q.front) { 
		Q.rear = Q.front->next; 
		delete Q.front; 
		Q.front = Q.rear; 
	}
	return OK; 
}
// 打印杨辉三角
void printPascalTriangle(int n){
	LinkQueue Q;
	InitQueue(Q);
	for(int i = 1; i <= n; i++){
		int size = QueueLength(Q); // 获取队列长度
		int prev = 0;
		for(int j = 0; j < n - i; j++) {
			cout << " "; // 打印前导空格
		}
		for(int j = 0; j < size; j++){
			QElemType curr;
			PopQueue(Q, curr);
			cout << prev + curr << " ";
			PushQueue(Q, prev + curr); // 将计算结果入队
			prev = curr;
		}
		cout << "1 " << endl; // 每行的最后一个元素是1
		PushQueue(Q, 1); // 将1入队,为下一行做准备
	}
}

int main(){
	int n;
	cin>>n;
	printPascalTriangle(n);
	return 0;
}

运行结果如下

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值