c++实现的Array数据结构

1.Array.h,Array<T>的定义

template <class T>
class Array
{
protected:
    T *data;    //一个指向数组数据的指针
    unsigned int base;    //base为数组的起始下表
    unsigned int length;    //length为数组的长度
public:
    Array();    //缺省的构造函数
    Array(unsigned int, unsigned int = 0);    //数组构造函数
    ~Array();    //析构函数

    Array(Array const&);    //拷贝构造函数
    Array& operator = (Array const&);    //重载等号操作符,用于一个数组给另外一个数组赋值

    T const& operator [] (unsigned int) const;    //重载中括号操作符,返回一个T数值常量,返回值不能被改变,在函数末尾加const表示this指针指向const
    T& operator [] (unsigned int);    //重载中括号操作符,返回一个T数值常量,其返回值可以被改变

    T* Data() const;    //返回数组数据的指针data
    unsigned int Base() const;    //返回成员base
    unsigned int Length() const;    //返回成员length

    void SetBase(unsigned int);    //设置成员变量base的数值
    void SetLength(unsigned int);    //设置成员变量length的数值
};

//动态数组所占空间S(n)=sizeof(T*)+2sizeof(unsigned int)+nsizeof(T),假定T类型所占用空间为一个常数,故S(n)=O(n)

2.Array<T>中成员函数的实现

#include "Array.h"

template <class T>
Array<T>::Array() :
    data(new T[10]),
    base(0),
    length(0)
{}
//缺省的构造函数不含变量,只需要给对象的变量一个初始值,时间复杂度O(1)

template <class T>
Array<T>::Array(unsigned int n, unsigned int m) :
    data(new T[n]),
    base(m),
    length(n)
{}
//初始化数组,n为数组的长度,时间复杂度常量O(1)

template <class T>
Array<T>::Array(Array<T> const& array) :
    data(new T[array.length]),
    base(array.base),
    length(array.length)
{
    for (unsigned int i = 0; i < length; ++i)
        data[i] = array.data[i];
}

//备份构造函数,将一个数组从赋值到另外一个数组,时间复杂度为O(n)

template <class T>
Array<T>::~Array()
{
    delete[] data;
}

//析构函数,删除数组所占用的内存空间

template <class T>
T* Array<T>::Data() const
{
    return data;
}

template <class T>
unsigned int Array<T>::Base() const
{
    return base;
}

template <class T>
unsigned int Array<T>::Length() const
{
    return length;
}

//这三个为存取器函数,用来返回成员,时间复杂度都为O(1)

template <class T>
T const& Array<T>::operator[] (unsigned int position) const
{
    unsigned int const offset = position - base;
    if (offset >= length)
        throw out_of_range("invalid position");
    return data[offset];
}

template <class T>
T& Array<T>::operator[] (unsigned int position)
{
    unsigned int const offset = position - base;
    if (offset >= length)
        throw out_of_range("invalid position");
    return data[offset];
}
//这两个都为取下表操作符的重载,区别是第一个返回值不可以作为左值,第二个返回值可以作为左值,时间复杂度都为O(1)

template <class T>
void Array<T>::SetBase(unsigned int newBase)
{
    base = newBase;
}

template <class T>
void Array<T>::SetLength(unsigned int newLength)
{
    T* const newData = new T[newLength];
    unsigned int const min = length < newLength ? length : newLength;
    for (unsigned int i = 0; i < min; ++i)
        newData[i] = data[i];
    delete[] data;
    data = newData;
    length = newLength;
}

//这两个函数来重设对象的成员,时间复杂度为T(m,n)=min(m,n)*T(T::T(T&))+O(1)

template <class T>
Array<T>& Array<T>::operator = (Array<T> const& array)
{
    if (this != &array)
    {
        delete[] data;
        base = array.base;
        length = array.length;
        data = new T[length];
        for (unsigned int i = 0; i < length; ++i)
            data[i] = array.data[i];
    }
    return this;
}

//重载赋值操作符,时间复杂度为O(n)

3.测试主函数main.cpp

#include "Array.cpp"
#include <iostream>
using namespace std;

template <class T> void Output(Array<T> array);

template <class T>
void Output(Array<T> array)
{
    cout << "data:";
    for (unsigned int i = array.Base(); i < array.Length(); i++)
    {
        cout << array.Data()[i] << " ";
    }
    cout << endl;
    cout << "length:" << array.Length()<<endl;
    cout << "base:" << array.Base() <<endl;
}

int main()
{
    cout << "Array()正在执行。。。" << endl;
    Array<int> array0 = Array<int>();
    Output(array0);
    cout << "Array(unsigned int, unsigned int = 0)正在执行。。。" << endl;
    Array<int> array1 = Array<int>(10);
    Output(array1);
    cout << "Array(Array const&)正在执行。。。" << endl;
    Array<int> array2(array1);
    Output(array2);
    cout << "~Array()正在执行。。。" << endl;
    array2.~Array();
    Output(array2);
    cout << "T const* Data() const,unsigned int Base() const,unsigned int Length() const,"
        << "T const& operator [] (unsigned int) const在Output函数中执行。。。" << endl;
    cout << "T& operator [] (unsigned int)正在执行。。。" << endl;
    Array<int> array3(10);
    for (unsigned int i = array1.Base(); i < array1.Length() - array1.Base(); i++)
    {
        array3.Data()[i] = i;
    }
    Output(array3);
    cout << "void SetBase(unsigned int)正在执行。。。" << endl;
    array3.SetBase(2);
    Output(array3);
    cout << "void SetLength(unsigned int)正在执行。。。" << endl;
    array3.SetLength(7);
    Output(array3);
    getchar();
    return 0;
}

4.测试结果

时间: 2025-01-04 08:50:52

c++实现的Array数据结构的相关文章

【Codeforces 722C】Destroying Array (数据结构、set)

题意 输入一个含有 n(1≤n≤100000) 个非负整数的 a 数组和一个 1-n 的排列 p 数组,求每次删除 a[p[i]] 后,最大连续子段和(不能跨越被删除的)是多少? 分析 因为都是非负整数,答案一定是尽量长的区间和. s[i] 表示 a 的前缀和,区间(l,r]的和就是s[r]-s[l]. 我们用 STL 里的 set 存区间,一开始只有(0,n]区间,删去第一个数后,就要去掉(0,n]区间,加上(0,p[1]-1]和(p[1],n]区间,类似地每次删除一个数,就要去掉包含它的区间

Spark性能优化指南——高级篇

Spark性能优化指南--高级篇 [TOC] 前言 继基础篇讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化指南>的高级篇,将深入分析数据倾斜调优与shuffle调优,以解决更加棘手的性能问题. 数据倾斜调优 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能. 数据倾斜发生时的现象 绝大多数tas

转:PHP并发IO编程之路

并发IO问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接Fork进程,到Worker进程池/线程池,到现在的异步IO.协程.PHP程序员因为有强大的LAMP框架,对这类底层方面的知识知之甚少,本文目的就是详细介绍PHP进行并发IO编程的各种尝试,最后再介绍Swoole的使用,深入浅出全面解析并发IO问题. 多进程/多线程同步阻塞 最早的服务器端程序都是通过多进程.多线程来解决并发IO的问题.进程模型出现的最早,从Unix系统诞生就开始有了进程的概念.最早的服务器端程序一般都是Accept

JavaScript数组知识网络

JavaScript数据类型 基本数据类型 Boolean Null Number String Symbol Undefined 对象数据类型Object Build-in object Array Date RegExp more... Array 定义:JavaScript数组是内置的对象之一,它可以用一个变量来存储多个同种类型或不同类型的值. 构造方法 var newArr = new Array(values); var newArr = [values]; 判断是否数组 Array.

PHP并发IO编程之路

并发IO问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接Fork进程,到Worker进程池/线程池,到现在的异步IO.协程.PHP程序员因为有强大的LAMP框架,对这类底层方面的知识知之甚少,本文目的就是详细介绍PHP进行并发IO编程的各种尝试,最后再介绍Swoole的使用,深入浅出全面解析并发IO问题. 多进程/多线程同步阻塞 最早的服务器端程序都是通过多进程.多线程来解决并发IO的问题.进程模型出现的最早,从Unix系统诞生就开始有了进程的概念.最早的服务器端程序一般都是Accept

【转载】Spark性能优化指南——高级篇

前言 数据倾斜调优 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 查看导致数据倾斜的key的数据分布情况 数据倾斜的解决方案 解决方案一:使用Hive ETL预处理数据 解决方案二:过滤少数导致倾斜的key 解决方案三:提高shuffle操作的并行度 解决方案四:两阶段聚合(局部聚合+全局聚合) 解决方案五:将reduce join转为map join 解决方案六:采样倾斜key并分拆join操作 解决方案七:使用随机前缀和扩容RDD进行join 解决方案八:多

Spark Shuffle原理、Shuffle操作问题解决和参数调优

摘要: 1 shuffle原理 1.1 mapreduce的shuffle原理 1.1.1 map task端操作 1.1.2 reduce task端操作 1.2 spark现在的SortShuffleManager 2 Shuffle操作问题解决 2.1 数据倾斜原理 2.2 数据倾斜问题发现与解决 2.3 数据倾斜解决方案 3 spark RDD中的shuffle算子 3.1 去重 3.2 聚合 3.3 排序 3.4 重分区 3.5 集合操作和表操作 4 spark shuffle参数调优

刷过的题 分类汇总

需要复习的算法题分类 二分搜索 ? 二叉树与分治part1:?    part2 ? 三种遍历 前序遍历 中序遍历 后续遍历 动态规划 ? 序列 dd dddd ddd linkedlist  ? array 中位数 median,quick sort subarray two pointers partition array 数据结构   part1 queue heap hashmap 并查集 trie树 扫描线 图搜索 回溯算法 part1  ? part2 ? 9. 各种排序 1. 基于

Spark性能调优——扩展篇

本文要解决的问题: 从更深层次考虑,对Spark进行性能调优. 目的 继基础篇分析了开发调优与资源调优之后,本文作为拓展篇,将深入分析数据倾斜调优与shuffle调优,以解决更加棘手的性能问题. 数据倾斜调优 简述 有时候,大家可能会遇到大数据开发过程中一个比较棘手的问题,那就是数据倾斜,此时Spark作业的性能会比预期差很多,数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能. 数据倾斜发生时的现象 绝大多数task执行得都非常快,但个别task执行极慢.