当前位置:   article > 正文

数据结构 - C/C++ - 数组

数据结构 - C/C++ - 数组

目录

结构特性

内存布局

结构样式

结构拓展

数据初始

元素访问

插入元素

删除元素

查找元素

修改元素

结构设计

成员变量

构造函数

功能函数

示例代码


结构特性

  • 长度固定:数组的长度在创建时已经被确定,如果需要动态改变数组的长度,可以考虑使用动态数组。

  • 连续性:数组中的所有元素在内存中是连续存储的。数组可以快速访问任意元素,单插入和删除操作会影响效率。

  • 一致性:数组中的所有元素必须都是相同的类型。

  • 索引:索引从0开始,数组下标上限长度减去1。

内存布局

  • 数组在内存中占据一块连续的内存空间。

  • 数组起始地址是数组首个元素的地址(数组名即为首地址)。

  • 每个元素占据的内存空间是相同的,具体大小取决于与元素的类型。

  • 通过索引可以快速访问数组中的任意元素。

    1. #include <iostream>
    2. int main()
    3. {
    4. int Arr[10] = { 1,3,2,5,4 };
    5. printf("Arr.BaseAddr -> %p \r\n", Arr);
    6. printf("Arr.BaseAddr -> %p \r\n", &Arr[0]);
    7. for (int Index = 0; Index < sizeof(Arr) / sizeof(Arr[0]); Index++)
    8. {
    9. printf("Arr[%d] -> %p -> %d \r\n", Index, &Arr[Index], Arr[Index]);
    10. }
    11. return 0;
    12. }

 

结构样式

  • 静态数组:编译时确定数组长度,无法在运行期间修改其长度。

  • 动态数组:运行时动态分配内存,可以在运行期间修改其长度。(C++STD::VECTOR)

结构拓展

数据初始

  1. #include <iostream>
  2. int main()
  3. {
  4. //stack
  5. int Arr1[5];
  6. int Arr2[5] = { 0 };
  7. int Arr3[] = { 1,2,3,4,5 };
  8. //heap
  9. int* p1 = new int[5];
  10. delete[] p1;
  11. int* p2 = new int[5]{ 1,2,3,4,5 };
  12. delete[] p2;
  13. return 0;
  14. }

元素访问

  • 内存图解
  • 实例代码
      1. #include <iostream>
      2. int main()
      3. {
      4. int Arr[5] = { 1,3,2,5,4 };
      5. Arr[0] = 1;
      6. Arr[1] = 2;
      7. Arr[2] = 3;
      8. Arr[3] = 4;
      9. Arr[4] = 5;
      10. return 0;
      11. }
  • 汇编分析 
      1. int Arr[5] = { 1,3,2,5,4 };
      2. 00414635 mov dword ptr [ebp-18h],1
      3. 0041463C mov dword ptr [ebp-14h],3
      4. 00414643 mov dword ptr [ebp-10h],2
      5. 0041464A mov dword ptr [ebp-0Ch],5
      6. 00414651 mov dword ptr [ebp-8],4
      7. Arr[0] = 1;
      8. 00414658 mov eax,4
      9. 0041465D imul ecx,eax,0
      10. 00414660 mov dword ptr [ebp+ecx-18h],1
      11. Arr[1] = 2;
      12. 00414668 mov eax,4
      13. 0041466D shl eax,0
      14. 00414670 mov dword ptr [ebp+eax-18h],2
      15. Arr[2] = 3;
      16. 00414678 mov eax,4
      17. 0041467D shl eax,1
      18. 0041467F mov dword ptr [ebp+eax-18h],3
      19. Arr[3] = 4;
      20. 00414687 mov eax,4
      21. 0041468C imul ecx,eax,3
      22. 0041468F mov dword ptr [ebp+ecx-18h],4
      23. Arr[4] = 5;
      24. 00414697 mov eax,4
      25. 0041469C shl eax,2
      26. 0041469F mov dword ptr [ebp+eax-18h],5
    • ebp-18h == 数组首地址

    • mov dword ptr [ebp+ecx-18h],1 == ebp-18h + 0 * 4

    • mov dword ptr [ebp+eax-18h],2 == ebp-18h + 1 * 4

    • mov dword ptr [ebp+eax-18h],3 == ebp-18h + 2 * 4

    • mov dword ptr [ebp+ecx-18h],4 == ebp-18h + 3 * 4

    • mov dword ptr [ebp+eax-18h],5 == ebp-18h + 4 * 4

插入元素

  • 插入步骤
  • 代码实现
      1. void Insert(int* p, int nLength, int nIndex, int nVar)
      2. {
      3. for (int i = nLength - 1; i > nIndex; i--)
      4. {
      5. p[i] = p[i - 1];
      6. }
      7. p[nIndex] = nVar;
      8. }

删除元素

  • 删除步骤
  • 代码实现
      1. void Remove(int* p, int nLength, int nIndex)
      2. {
      3. for (int i = nIndex; i < nLength - 1; i++)
      4. {
      5. p[i] = p[i + 1];
      6. }
      7. }

查找元素

    1. int Find(int* p, int nLength, int nVar)
    2. {
    3. for (int i = 0; i < nLength; i++)
    4. {
    5. if (p[i] == nVar)
    6. {
    7. return i;
    8. }
    9. }
    10. return -1;
    11. }

修改元素

    1. int Arr[6] = { 1,2,3,4,5 };
    2. Arr[0] = 11;
    3. *(Arr + 1) = 22;

结构设计

成员变量

  1. T* data; //动态数组指针
  2. int size; //数组元素个数
  3. int capacity; //数组容量大小

构造函数

  • 默认构造函数
  • 有参构造函数
  • 拷贝构造函数
  • 移动构造函数
  • 列表构造函数

功能函数

  • 元素个数
  • 数组容量
  • 是否为空
  • 下标访问
  • 插入元素
  • 删除元素
  • 查找元素

示例代码

  1. #include <iostream>
  2. #include <vector>
  3. template <typename T>
  4. class Vector
  5. {
  6. private: //成员变量
  7. T* data; //动态数组指针
  8. int size; //数组元素个数
  9. int capacity; //数组容量大小
  10. public: //构造析构
  11. //默认构造函数
  12. Vector() : data(nullptr), size(0), capacity(0)
  13. {
  14. }
  15. //有参构造函数
  16. Vector(int size, const T& var) : size(size), capacity(size)
  17. {
  18. this->data = new T[capacity];
  19. for (size_t i = 0; i < capacity; i++)
  20. {
  21. data[i] = var;
  22. }
  23. }
  24. //拷贝构造函数
  25. Vector(const Vector& ref) : size(ref.size), capacity(ref.capacity)
  26. {
  27. this->data = new T[capacity];
  28. for (size_t i = 0; i < capacity; i++)
  29. {
  30. this->data[i] = ref.data[i];
  31. }
  32. }
  33. //移动构造函数
  34. Vector(Vector&& other)noexcept : data(other.data), size(other.size), capacity(other.capacity)
  35. {
  36. other.data = nullptr;
  37. other.size = 0;
  38. other.capacity = 0;
  39. }
  40. //列表构造函数
  41. Vector(std::initializer_list<T> initlist) : size(initlist.size()), capacity(initlist.size())
  42. {
  43. this->data = new T[capacity];
  44. int i = 0;
  45. for (const auto& value: initlist)
  46. {
  47. data[i++] = value;
  48. }
  49. }
  50. //默认析构函数
  51. ~Vector()
  52. {
  53. if (this->data != NULL)
  54. {
  55. delete[] this->data;
  56. }
  57. }
  58. public: //成员函数
  59. //获取元素个数
  60. int Size() const
  61. {
  62. return this->size;
  63. }
  64. //获取数组容量
  65. int Capacity() const
  66. {
  67. return this->capacity;
  68. }
  69. //数组是否为空
  70. bool Empty()
  71. {
  72. return this->size == 0 ? true : false;
  73. }
  74. //下标获取元素
  75. T& operator[](int nIndex)
  76. {
  77. return this->data[nIndex];
  78. }
  79. //末尾追加元素
  80. void Push_Back(const T& value)
  81. {
  82. //判断容器容量
  83. if (this->size >= this->capacity)
  84. {
  85. //容量大小修正
  86. capacity = (capacity == 0) ? 1 : capacity * 2;
  87. //申请扩容内存
  88. T* tempData = new T[capacity];
  89. //拷贝默认数据
  90. for (int i = 0; i < size; i++)
  91. {
  92. tempData[i] = this->data[i];
  93. }
  94. //释放默认内存
  95. delete[] this->data;
  96. //修正数据指针
  97. this->data = tempData;
  98. }
  99. this->data[size] = value;
  100. - size++;
  101. }
  102. //插入元素数据
  103. void Insert(int nIndex, const T& value)
  104. {
  105. //判断索引序号
  106. if (nIndex < 0 || nIndex > size)
  107. {
  108. throw std::out_of_range("Invalid Index");
  109. }
  110. //判断容器容量
  111. if (this->size >= this->capacity)
  112. {
  113. //容量大小修正
  114. capacity = (capacity == 0) ? 1 : capacity * 2;
  115. //申请扩容内存
  116. T* tempData = new T[capacity];
  117. //拷贝默认数据
  118. for (int i = 0; i < size; i++)
  119. {
  120. tempData[i] = this->data[i];
  121. }
  122. //释放默认内存
  123. delete[] this->data;
  124. //修正数据指针
  125. this->data = tempData;
  126. }
  127. //指定位置插入
  128. for (int i = size; i > nIndex; i--)
  129. {
  130. this->data[i] = this->data[i - 1];
  131. }
  132. this->data[nIndex] = value;
  133. this->size++;
  134. }
  135. //删除元素数据
  136. void erase(int nIndex)
  137. {
  138. //判断索引序号
  139. if (nIndex < 0 || nIndex > size)
  140. {
  141. throw std::out_of_range("Invalid Index");
  142. }
  143. //删除指定元素
  144. for (int i = nIndex; i < this->size -1; i++)
  145. {
  146. this->data[i] = this->data[i + 1];
  147. }
  148. //修正数组个数
  149. //this->data[this->size - 1] = 0;
  150. this->size--;
  151. }
  152. //查找指定元素
  153. int Find(const T& valud) const
  154. {
  155. for (size_t i = 0; i < this->size; i++)
  156. {
  157. if (this->data[i] == valud)
  158. {
  159. return i;
  160. }
  161. }
  162. return -1;
  163. }
  164. };
  165. int main()
  166. {
  167. //默认构造函数
  168. Vector<int> vec1;
  169. //有参构造函数
  170. Vector<int> vec2(3, 0xCC);
  171. //拷贝构造函数
  172. Vector<int> vec3(vec2);
  173. //移动构造函数
  174. Vector<int> vec4(std::move(vec3));
  175. //列表构造函数
  176. Vector<int> vec5 = { 1,2,3,4,5 };
  177. return 0;
  178. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/508015
推荐阅读
相关标签
  

闽ICP备14008679号