C++数据结构队列实现之面向过程编程,此次试验测试库函数由马光志老师编写,测试成功会输出successed 并输出相应得分。测试库配置会在末尾给出,不能上传附件,需要测试库的小伙伴可以私信。以上。
马光志的《C++程序设计实践教程》这本书怎么样?www.zhihu.comemmm,照例一句:“喜欢你以后,我感觉整个人轻松多了。我那么一个阴郁孤僻的小孩,好像一盏坏掉了的灰扑扑的灯,突然被拉闸了,整个人都火花带闪电的,温柔地亮了一会。”
一、需求分析
1. 题目要求
整型队列是一种先进先出的存储结构,对其进行的操作通常包括:向队列尾部添加一个整型元素、从队列首部移除一个整型元素等。整型循环队列类型Queue及其操作函数采用非面向对象的C语言定义,请将完成上述操作的所有如下函数采用C语言编程, 然后写一个main函数对队列的所有操作函数进行测试,请不要自己添加定义任何新的函数成员和数据成员。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
struct Queue{
int* const elems; //elems申请内存用于存放队列的元素
const int max; //elems申请的最大元素个数max
int head, tail; //队列头head和尾tail,队空head=tail;初始head=tail=0
};
void initQueue(Queue *const p, int m); //初始化p指队列:最多申请m个元素
void initQueue(Queue *const p, const Queue&s); //用s深拷贝初始化p指队列
void initQueue(Queue *const p, Queue&&s); //用s移动初始化p指队列
int number (const Queue *const p); //返回p指队列的实际元素个数
int size(const Queue *const p); //返回p指队列申请的最大元素个数max
Queue*const enter(Queue*const p, int e); //将e入队列尾部,并返回p
Queue*const leave(Queue*const p, int &e); //从队首出元素到e,并返回p
Queue*const assign(Queue*const p, const Queue&q); //深拷贝赋s给队列并返回p
Queue*const assign(Queue*const p, Queue&&q); //移动赋s给队列并返回p
char*print(const Queue *const p, char*s);//打印p指队列至s尾部并返回s:s[0]=’0’
void destroyQueue (Queue *const p); //销毁p指向的队列
编程时应采用VS2019开发,并将其编译模式设置为X86模式,其他需要注意的事项说明如下:
(1)用initQueue(Queue *const p, int m)对p指向的队列初始化时, 为其elems分配m个整型元素内存,并初始化max为m,以及初始化head=tail=0。
(2)对于initQueue(Queue *const p, const Queue& q)初始化,用已经存在的对象q深拷贝构造新对象*p时,新对象*p不能和对象q的elems共用同一块内存,新对象*p的elems需要分配和q为elems分配的同样大小的内存,并且将已经存在q的elems的内容深拷贝至新分配的内存;新对象*p的max、head、tail应设置成和已经存在的对象s相同。
(3)对于initQueue(Queue *const p, Queue&& q)初始化,用已经存在的对象q移动构造新对象,新对象使用对象q为elems分配的内存快,并将其max、head、tail设置成和s的对应值相同,然后将s的elems设置为空表示内存已经移动给新对象,将s的max、head、tail设置为0。
(4)对于Queue*const assign(Queue*const p, const Queue&q)深拷贝赋值,用等号右边的对象q深拷贝赋值给等号左边的对象,等号左边的对象如果已经有内存则应先释放以避免内存泄漏,然后分配和对象q为elems分配的同样大小的内存,并且设置其max、head、tail和q的对应值相同。
(5)对于Queue*const assign(Queue*const p, Queue&&q)移动赋值,若等号左边的对象为elems分配了内存,则先释放改内存一面内存泄漏,然后使用等号右边对象q为elems分配的内存,并将其max、head、tail设置成和对象q的对应值相同;对象q的elems设置为空指针以表示内存被移走给等号左边的对象,同时其max、head、tail均应设置为0。
(6)队列应实现为循环队列,当队尾指针tail快要追上队首指针head时,即如果满足(tail+1)%max=head,则表示表示队列已满,故队列最多存放max-1个元素;而当head=tail时则表示队列为空。
(7)打印队列时从队首打印至队尾。
2. 需求分析
要求用C++实现以先进先出为存储结构的整型队列,具体实现以下操作函数:向队列尾部添加一个整型元素、从队列首部移除一个整型元素等。
整型循环队列类型Queue及其操作函数采用非面向对象的C++语言定义。请将完成上述操作的所有如下函数采用C++语言编程, 然后写一个main函数对队列的所有操作函数进行测试库测试,不要添加定义任何新的函数成员和数据成员,不修改任何定义借口参数。
二、系统设计
1. 概要设计
本实验主要通过指针和new函数分配内存以及强制类型转换方式实现对队列的初始化,入队出队列操作,及队列的删除释放等操作函数。需要关键注意的是我们要实现的队列是个循环队列,所以要对所有关于队首和队尾操作出仅需相应处理。
包括主函数模块,类定义模块,操作函数模块和测试库函数模块。模块间相应的层次结构为:主函数模块调用测试库函数,测试库函数调用操作函数模块,操作函数模块基于类定义模块设计。
三、测试:
1.测试库载入操作:
2.测试库成功输出:
四、代码:
//
// main.cpp
// 实验一
//
// Created by Azure on 2020/9/26.
// Copyright © 2020 Azure. All rights reserved.
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
FILE *fp;
struct Queue {
int* const elems; //elems申请内存用于存放队列的元素
int max; //elems申请的最大元素个数max
int head, tail; //队列头head和尾tail,队空head=tail;初始head=tail=0
};
void initQueue(struct Queue *const p, int m); //初始化p指队列:最多申请m个元素,bingo
void initQueue(struct Queue *const p, const struct Queue&s); //用s深拷贝初始化p指队列,bingo
void initQueue(struct Queue *const p, struct Queue&&s); //用s移动初始化p指队列,bingo
int number(const struct Queue *const p); //返回p指队列的实际元素个数,bingo
int size(const struct Queue *const p); //返回p指队列申请的最大元素个数max,bingo
struct Queue*const enter(struct Queue*const p, int e); //将e入队列尾部,并返回p,bingo
struct Queue*const leave(struct Queue*const p, int &e); //从队首出元素到e,并返回p,bingo
struct Queue*const assign(struct Queue*const p, const struct Queue&q); //深拷贝赋s给队列并返回p,bingo
struct Queue*const assign(struct Queue*const p, struct Queue&&q); //移动赋s给队列并返回p,bingo
char*print(const struct Queue *const p, char*s);//打印p指队列至s尾部并返回s:s[0]=’0’
void destroyQueue(struct Queue *const p); //销毁p指向的队列
extern const char*TestQueue(int &s);
int main(int argc, const char * argv[]) {
const char *e;
int s;
e = TestQueue(s);
cout << e << endl;
cout << s << endl;
return 0;
}
//初始化p指队列:最多申请m个元素
void initQueue(struct Queue * const p, int m) {
cout << "func1" << endl;
if (p->max != 0) {
p->head=p->tail=0;
*(int*)&(p->max) = 0;
*(int**)&(p->elems) = NULL;
}
*(int*)&(p->max) = m;
*(int**)&(p->elems) = (int *)malloc(sizeof(int)*m);
p->head = p->tail = 0;
}
//用s深拷贝初始化p指队列
void initQueue(struct Queue *const p, const struct Queue&s) {
cout << "func2" << endl;
if (p->max != 0) {
p->head = p->tail = 0;
*(int*)&(p->max) = 0;
*(int**)&(p->elems) = NULL;
}
const struct Queue *q = &s;
if (s.elems != NULL) {
int m = 0;
m = s.max;
int *a = new int[m];
for (int i = s.head; i !=s.tail; i=(i++)%m) {
a[i] = s.elems[i];
}
*(int*)&(p->max) = m;
*(int**)&(p->elems) = a;
p->head = q->head;
p->tail = q->tail;
}
}
//用s移动初始化p指队列
void initQueue(struct Queue *const p, struct Queue&&s) {
cout << "func3" << endl;
if (p->max != 0) {
p->head = p->tail = 0;
*(int*)&(p->max) = 0;
*(int**)&(p->elems) = NULL;
}
const struct Queue *q = &s;
p->head = q->head;
p->tail = q->tail;
s.head = 0; s.tail = 0;
int m;
m = q->max;
*(int*)&(p->max) = m;
*(int**)&(p->elems) = q->elems;
*(int**)&(q->elems) = NULL;
*(int*)&(q->max) = 0;
}
//返回p指队列的实际元素个数
int number(const struct Queue *const p) {
cout << "func4" << endl;
if (p->max == 0) {
return 0;
}
int num = 0;
int temp1, temp2;
temp1 = p->tail;
temp2 = p->head;
num = temp1 - temp2;
if (num < 0) {
num = num + p->max;
}
return num;
}
//返回p指队列申请的最大元素个数max
int size(const struct Queue *const p) {
cout << "func5" << endl;
if (p->max == 0) {
return 0;
}
int ma;
ma = p->max;
return ma;
}
//将e入队列尾部,并返回p
struct Queue*const enter(struct Queue*const p, int e) {
cout << "func6" << endl;
int t = p->tail;
int h = p->head;
int m = p->max;
if ((t + 1) % m == h) {
throw "Queue is full!";
}
((int*)(p->elems))[t] = e;
t++;
t = t % m;
p->tail = t;
return p;
}
//从队首出元素到e,并返回p
struct Queue*const leave(struct Queue*const p, int &e) {
cout << "func7" << endl;
int *q = &e; int wro=0;
int h;h = p->head;
int m;m = p->max;
int x;x = p->tail;
if (x == h) {
throw "Queue is empty!" ;
}
*q = (p->elems)[h];
h++;
h = h % m;
p->head = h;
return p;
}
//深拷贝赋s给队列并返回p
struct Queue*const assign(struct Queue*const p, const struct Queue&q) {
cout << "func8" << endl;
if (p->elems != NULL) {
*(int**)&(p->elems) = NULL;
}
int m = 0;
m=q.max;
*(int*)&(p->max) = m;
int *a;
a= (int *)malloc(sizeof(int)*m);
int h = q.head; p->head = h;
int t = q.tail; p->tail = t;
for (int i = h; i != t; i = (i++) % m) {
a[i] = q.elems[i];
}
*(int**)&(p->elems) = a;
return p;
}
//移动赋s给队列并返回p
struct Queue*const assign(struct Queue*const p, struct Queue&&q) {
cout << "func9" << endl;
if (p->elems != NULL) {
*(int**)&(p->elems) = NULL;
}
*(int**)&(p->elems) = q.elems;
*(int*)&(p->max) = q.max;
p->head =q.head;p->tail = q.tail;
struct Queue *ptr = &q;
*(int**)&(ptr->elems) = NULL;
*(int*)&(ptr->max) = 0;
q.head = 0;q.tail = 0;
return p;
}
//打印p指队列至s尾部并返回s:s[0]=’0’
char*print(const struct Queue *const p, char*s) {
cout << "func10" << endl;
int m = p->max;
for (int i = p->head; i !=p->tail;i=(i+1)%m) {
char * ss = s + strlen(s);
sprintf(ss, "%d,", p->elems[i]);
}
return s;
}
//销毁p指向的队列
void destroyQueue(struct Queue *const p) {
cout << "func11" << endl;
*(int**)&(p->elems) =NULL;
*(int*)&(p->max) = 0;
p->head = p->tail = 0;
}