面向过程的整形队列编程

C++实验一

面向过程的整形队列编程

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include<malloc.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
void destroyQueue(Queue* const p);	 //销毁p指向的队列
void initQueue(Queue* const p, int m) {
    if (p == nullptr){
        throw"The pointer must have allocated memory!";
        return;
    }
    (int&)p->max = m; //强制类型转换为可写的指针
    (int*&)p->elems = new int[m];
    //*(int**)&(p->elems) = new int[m]; 这两种写法一样
    // 相当于把只读的指针变量,强制转换为可写的指针变量
    //cout << p->max << endl;
    p->head = 0;
    p->tail = 0;
}

void initQueue(Queue* const p, const Queue& s) {
    //深拷贝的核心是:拷贝的内存块不要共用
    if (p == nullptr){
        throw"The pointer must have allocated memory!";
        return;
    }   
    p->head = s.head;
    p->tail = s.tail;
    (int&)p->max = s.max;
    (int*&)p->elems = new int[s.max];
    //初始化p
    int i = s.head;
    while (i != s.tail) {
        //当i指向数组头时,说明已经复制完毕
        p->elems[i] = s.elems[i];
        i++;
        i = i % p->max;
    }
    //深拷贝完成
}

void initQueue(Queue* const p, Queue&& s) {
    //核心是两个对象用同一个内存块,相当于把前一个对象的内存块移动走了
    if (p == nullptr){
        throw"The pointer must have allocated memory!";
        return;
    }
    if (p == &s) {
        throw"Can't init a queue which is already inited!";
        return;
    }
    p->head = s.head;
    p->tail = s.tail;
    (int&)p->max = s.max;
    //构造p
    (int*&)p->elems = s.elems;
    //内存移动
    (int *&)s.elems = nullptr;
    s.head = 0;
    s.tail = 0;
    (int&)s.max = 0;
    //处理s
}

int  number(const Queue* const p) {
    if (p->elems == nullptr)return NULL;//防止出现已经析构的队列访问number
    int head = p->head;
    int tail = p->tail;
    int max = p->max;
    return (tail - head + max) % max;
}

int  size(const Queue* const p) {
    return p->max;
}

Queue* const enter(Queue* const p, int e) {
    int head = p->head;
    int tail = p->tail;
    //cout << number(p)<<endl;
    //cout << p->max << endl;
    if ((tail+1) % p->max == head) {
        throw"Queue is full!";
        return p;
    }
    p->elems[tail] = e;
    p->tail = (p->tail+1) % (p->max);
    //改变的时候都要确保不会出现访问到数组外
    return p;
}

Queue* const leave(Queue* const p, int& e) {
    if (p->head == p->tail) {
        throw"Queue is empty!";
        return p;
    }
    e = p->elems[p->head];
    p->head = (p->head+1) % (p->max);
    return p;
}

Queue* const assign(Queue* const p, const Queue& q) {
    //深拷贝
    p->head = q.head;
    p->tail = q.tail;
    (int &)p->max = q.max;
    for (int i = 0; i < p->max; i++) {
        p->elems[i] = q.elems[i];
    }
    return p;
}

Queue* const assign(Queue* const p, Queue&& q) {
    //移动语义
    if (p == &q)return p;
    if (p->elems!=nullptr)delete []p->elems;
    //initQueue(p, q);
    (int*&)(p->elems) = q.elems;
    (int&)(p->max) = q.max;
    p->head = q.head;
    p->tail = q.tail;
    (int*&)(q.elems) = nullptr;
    (int&)(q.max) = 0;
    q.head = q.tail = 0;
    return p;
}

char* print(const Queue* const p, char* s) {
    if (p->max == 0) {
        throw"Can't print a nonexistent Queue!";
        return nullptr;
    }
    char* q = s;
    int i = p->head;
    while (i != p->tail) {
        if(i==p->head)sprintf(q, "%d", p->elems[i]);//第一个不能加(+strlen(q))否则会出现烫烫烫烫
        else sprintf(q+strlen(q), "%d", p->elems[i]);//向s字符串中打印元素
        if (i!=(p->tail-1)%p->max)
        sprintf(q+strlen(q), ",");//向s字符串中打印逗号
        i++;
        if (i == p->max) i = 0;//下标回传
    }//会自动打印'\0'的,不需要再额外添加
    return s;
}

void destroyQueue(Queue* const p) {
    if (p->elems != nullptr) {
        delete[]p->elems;
        (int*&)p->elems = nullptr;
        (int &)p->max = 0;
    }
    else throw"Can't deconstruct an invild queue!";
}
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值