C++数据结构之:数组Array

摘要:

  it人员无论是使用哪种高级语言开发东东,想要更高效有层次的开发程序的话都躲不开三件套:数据结构,算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系,分为逻辑结构和存储结构。
  此系列专注讲解数据结构数组、链表、队列、栈、树、图,通过介绍概念以及提及一些可能适用的场景,并以C++代码简易实现,多方面认识数据结构,最后为避免重复造轮子会浅提对应的STL容器。本文介绍的是数组Array。

(开发环境:VScode,C++17)

关键词C++数据结构数组Array

声明:本文作者原创,转载请附上文章出处与本文链接。

正文:

介绍:

  数组是最简单、使用最频繁的一种数据结构,它是一种线性表数据结构,除了第一个元素以外,集合中的每个数据元素均只有一个前驱,除了最后一个元素以外,集合中每个元素均只有一个后继,用一组连续的内存空间,来存储一组具有相同类型的数据。

在这里插入图片描述

特性:
  • 静态大小:在创建数组时,需要指定数组的大小,一旦创建,数组的大小就固定不变,不能动态修改。这意味着在数组的生命周期内,元素的数量是固定的。
  • 连续存储:数组中的所有元素都存储在连续的内存位置上。这种连续性使得数组具有随机访问的特性,即可以通过索引直接访问数组中的任意元素,而不需要遍历整个数组。
  • 相同类型:数组中的所有元素都必须是同一类型。这确保了数组在内存中的一致性和可管理性。
应用:
  • 数值计算:在科学计算和工程应用中,数组经常用于存储和处理大量的数值数据。
  • 图像处理:在图像处理中,像素值通常存储在一个二维数组中。
  • 数据结构和算法:许多其他数据结构(如栈、队列、列表等)都是基于数组实现的。
  • 数据库:在数据库中,索引通常使用数组来实现,以加快数据检索的速度。
代码实现:
#carray.h
#ifndef CARRAY_H
#define CARRAY_H
#include<iostream>

#define MAX_SIZE 256
using namespace std;

template <class T>
class CArray
{
public:
    CArray();                                   // 构造函数
    CArray(unsigned int, unsigned int = 0);     // 数组构造函数
    ~CArray();                                  // 析构函数

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

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

    void setBase(unsigned int);                 // 设置成员变量base的数值
    void setLength(unsigned int);               // 设置成员变量length的数值

    T* data() const;                            // 返回数组数据的指针m_pData
    unsigned int getBase() const;               // 返回成员base
    unsigned int getLength() const;             // 返回成员length
    void print();                               // 打印数组内容以及各属性

private:
    T *m_pData;             // 指向数组数据的指针
    unsigned int base;      // base为数组的起始下标
    unsigned int length;    // length为数组的长度
};

// 构造函数不含变量,只需要给对象的变量一个初始值
template <class T>
CArray<T>::CArray() : m_pData(new T[MAX_SIZE]),base(0),length(0)
{
}

// 初始化数组,n为数组的长度
template <class T>
CArray<T>::CArray(unsigned int n, unsigned int m) : m_pData(new T[n]),base(m),length(n)
{
}

// 析构函数,删除数组所占用的内存空间
template <class T>
CArray<T>::~CArray()
{
    delete[] m_pData;
    m_pData = nullptr;
}

// 拷贝构造函数,将一个数组从赋值到另外一个数组
template <class T>
CArray<T>::CArray(CArray<T> const& CArray) :
  m_pData(new T[CArray.length]),
  base(CArray.base),
  length(CArray.length)
{
    for (unsigned int i = 0; i < length; ++i)
        m_pData[i] = CArray.m_pData[i];
}

// 重载赋值操作符
template <class T>
CArray<T>& CArray<T>::operator = (CArray<T> const& CArray)
{
    if (this != &CArray){
        delete[] m_pData;
        base = CArray.base;
        length = CArray.length;
        m_pData = new T[length];
        for (unsigned int i = 0; i < length; ++i)
        m_pData[i] = CArray.m_pData[i];
    }
    return this;
}

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

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

template <class T>
void CArray<T>::setLength(unsigned int newLength)
{
    T* const newm_pData = new T[newLength];
    unsigned int const min = length < newLength ? length : newLength;
    for (unsigned int i = 0; i < min; ++i)
        newm_pData[i] = m_pData[i];
    delete[] m_pData;
    m_pData = newm_pData;
    length = newLength;
}

template <class T>
T* CArray<T>::data() const
{
    return m_pData;
}

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

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

template <class T>
void CArray<T>::print()
{
    cout << "m_pData:";
    for (unsigned int i = base; i < length; i++){
        cout << m_pData[i] << " ";
    }
    cout << endl;
    cout << "length:" << length << endl;
    cout << "base:" << base << endl;
}

#endif // !CARRAY_H
#carray.cpp
#include "carray.h"
using namespace std;

int main(int argc, char** argv)
{
  CArray<int> CArray0 = CArray<int>();
  CArray0.print();
  cout << endl;

  CArray<int> CArray1 = CArray<int>(10);
  CArray1.print();
  cout << endl;

  CArray<int> CArray2(CArray1);
  CArray2.print();
  cout << endl;
  CArray2.~CArray();

  CArray<int> CArray3(10);
  for (unsigned int i = CArray1.getBase(); i < CArray1.getLength() - CArray1.getBase(); i++){
    CArray3.data()[i] = i;
  }
  CArray3.print();
  cout << endl;

  CArray3.setBase(2);
  CArray3.print();
  cout << endl;

  CArray3.setLength(7);
  CArray3.print();
  return 0;
}

在这里插入图片描述

对应STL:
  • string

    string类本不是STL的容器,但是它与STL容器有着很多相似的操作,C++中的string类相当于是字符数组,但是其更方便于我们的操作,而且不需要在输入之前初始化字符数组的容量,节省空间。

  • array

    array即数组,其大小固定,所有的元素严格按照内存地址线性排列,array 并不维护元素之外的任何多余数据,甚至也不会维护一个size这样的变量,这保证了它在存储性能上和C++语法中的数组符号[]无异。

  • vector

    vector 就是能够动态调整大小的 array。和 array 一样,vector 使用连续内存空间来保存元素,这意味着其元素可以用普通指针的++和–操作来访问;不同于 array 的是,其存储空间可以自动调整。

  • bitset

    bitset容器相当于是01数组,其方便之处是可以直接按位(下标)进行位运算,但是要注意下标从小到大依次存低位到高位,是逆序的。

推荐阅读

C/C++专栏:
https://blog.csdn.net/weixin_45068267/category_12268204.html
(后续会更新更多数据结构以及对应的STL容器使用)

(画饼ing:)

C++数据结构之:链List:

C++数据结构之:队Queue:

C++数据结构之:栈Stack:

C++数据结构之:堆Heap:

C++数据结构之:树Tree:

C++数据结构之:图Graph:

C++ STL容器:序列式容器-数组string,vector,array,bitset:

  • 35
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值