C++实现循环队列和链式队列操作(实验5--作业)
循环队列
一、主要功能
实现了顺序队列(SqQueue)的数据结构,并利用该队列实现了打印前n
行杨辉三角的功能。
二、数据结构定义
- 定义了一些常量:
MAXSIZE
表示队列的最大长度为 100。OVERFLOw
表示存储失败的错误码为 -2。OK
和ERROR
分别表示操作成功和失败的状态码。
- 定义了数据类型:
Status
为int
类型,用于表示操作的状态。QElemType
为int
类型,代表队列中存储的数据类型。
- 定义了顺序队列结构体
SqQueue
:QElemType *base
是指向存储队列元素的数组的指针。int front
表示队首指针。int rear
表示队尾指针。
三、函数功能
InitQue
函数:用于初始化顺序队列,为队列分配内存空间,并设置队首和队尾指针为 0。QueueLength
函数:计算队列的长度,通过队尾指针减去队首指针再加上最大长度取余的方式来处理循环队列的情况。QueuePush
函数:将元素入队,如果队列已满则返回错误状态。采用牺牲一个存储单元的方法判断队列是否已满,即当队尾指针的下一个位置等于队首指针时认为队列已满。QueuePop
函数:将队首元素出队,如果队列为空则返回错误状态。出队后更新队首指针。GetQueueHead
函数:获取队首元素的值,如果队列为空则不返回任何值。printPascalTriangle
函数:打印前n
行杨辉三角。使用顺序队列,通过不断出队、计算和入队的方式生成杨辉三角的每一行,同时打印前导空格以实现三角形的对齐。最后一行的最后一个元素总是 1,每次循环结束后将 1 入队为下一行做准备。
四、主函数流程
- 从用户输入获取要打印的杨辉三角的行数
n
。 - 调用
printPascalTriangle
函数打印杨辉三角。
#include<bits/stdc++.h>//万能头文件
using namespace std;//命名空间#define MAXSIZE 100 //最大长度
#define OVERFLOw -2
#define OK 1
#define QElemType int
#define ERROR 0typedef 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; // 每行的最后一个元素是1QueuePush(Q, 1); // 将1入队,为下一行做准备}
}int main(){int n;cin>>n;printPascalTriangle(n);return 0;
}
链式队列
一、主要功能
实现了链式队列(LinkQueue)的数据结构,并利用该队列实现了打印前n
行杨辉三角的功能。
二、数据结构定义
- 定义了一些常量:
MAXSIZE
表示队列的最大长度为 100(在链式队列中未实际用到)。OVERFLOw
表示存储失败的错误码为 -2。OK
和ERROR
分别表示操作成功和失败的状态码。
- 定义了数据类型:
Status
为int
类型,用于表示操作的状态。QElemType
为int
类型,代表队列中存储的数据类型。
- 定义了链式队列的节点结构体
QNode
:QElemType data
表示节点存储的数据。struct QNode *next
指向下一个节点的指针。QueuePtr
是指向QNode
的指针类型别名。
- 定义了链式队列结构体
LinkQueue
:QueuePtr front
表示队头指针,指向队列的头节点。QueuePtr rear
表示队尾指针,指向队列的最后一个节点。
三、函数功能
InitQueue
函数:用于初始化链式队列,创建一个头节点,并将队头指针和队尾指针都指向该头节点,同时将头节点的next
指针置为NULL
。PushQueue
函数:将元素入队,创建一个新节点,设置其数据域为给定元素,将新节点插入到队尾,更新队尾指针指向新节点。PopQueue
函数:将队首元素出队,如果队列为空则返回错误状态。出队时,取出队首节点的数据,更新队头指针指向下一个节点,如果出队前队列只有一个元素,出队后需更新队尾指针使其与队头指针相同,表示队列为空。最后释放出队节点的内存空间。GetQueueHead
函数:获取队首元素的值,如果队列为空则返回 0。QueueLength
函数:计算链式队列的长度,通过遍历队列节点来统计节点个数。DestroyQueue
函数:销毁链式队列,通过不断释放节点内存空间并更新队头指针的方式,将队列完全销毁。printPascalTriangle
函数:打印前n
行杨辉三角。使用链式队列,通过不断出队、计算和入队的方式生成杨辉三角的每一行,同时打印前导空格以实现三角形的对齐。最后一行的最后一个元素总是 1,每次循环结束后将 1 入队为下一行做准备。
四、主函数流程
- 从用户输入获取要打印的杨辉三角的行数
n
。 - 调用
printPascalTriangle
函数打印杨辉三角。
#include<bits/stdc++.h>//万能头文件
using namespace std;//命名空间#define MAXSIZE 100 //最大长度
#define OVERFLOw -2
#define OK 1
#define QElemType int
#define ERROR 0typedef 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;//队尾的下一个指向pQ.rear->next = p;//队尾更新为pQ.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; // 每行的最后一个元素是1PushQueue(Q, 1); // 将1入队,为下一行做准备}
}int main(){int n;cin>>n;printPascalTriangle(n);return 0;
}