数据结构中的数组——动态数组的创建
1,StaticArray 确实可以代替原生数组使用,但是在创建 StaticArray 对象时,数组大小必须明确指定,能不能创建一个对象在使用过程中,对象的大小可以动态指定,且功能超越 StaticArray;
2,课程目标:
1,本节课完成 DynamicArray 类的创建,;
2,Dynamic 指的是数组的大小可以动态指定;
3,DynamicArray 设计要点:
1,类模板:
1,动态确定内部数组空间的大小;
2,实现函数返回数组长度;
3,拷贝构造和赋值操作;
4,动态重置数组大小;
4,DynamicArray 类的声明:
5,DynamicArray 动态数组的实现:
1 #ifndef DYNAMICARRAY_H 2 #define DYNAMICARRAY_H 3 4 #include "Array.h" 5 #include "Exception.h" 6 7 namespace DTLib 8 { 9 10 template <typename T> 11 class DynamicArray : public Array<T> 12 { 13 protected: 14 int m_length; 15 16 T* copy(T* array, int length, int newlength) // O(min(len, newlen)) ==> O(n); 17 { 18 T* ret = new T[newlength]; 19 if( ret != NULL ) 20 { 21 int size = ((length < newlength) ? length : newlength); 22 for(int i=0; i<size; i++) 23 { 24 ret[i] = array[i]; 25 } 26 } 27 return ret; 28 } 29 30 void update(T* array, int length) // O(1) 31 { 32 if( array != NULL ) 33 { 34 T* temp = this->m_array; 35 this->m_array = array; 36 this->m_length = length; 37 delete[] temp; 38 } 39 else 40 { 41 THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to update DynamicArray object ..."); 42 } 43 } 44 45 void init(T* array, int length) // O(1) 46 { 47 if( array != NULL ) 48 { 49 this->m_array = array; 50 this->m_length = length; 51 } 52 else 53 { 54 THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to init DynamicArray object ..."); 55 } 56 } 57 58 public: 59 DynamicArray(int length = 0) // O(1) 动态数组如果不指定大小,则默认的数组大小为零; 60 { 61 init(new T[length], length); 62 /* 63 this->m_array = new T[length]; 64 if(this->m_array != NULL) 65 { 66 this->m_length = length; 67 } 68 else 69 { 70 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create DynamicArray object ..."); 71 } 72 */ 73 } 74 75 DynamicArray(const DynamicArray<T>& obj) // O(n) 76 { 77 init(copy(obj.m_array, obj.m_length, obj.m_length), obj.m_length); 78 /* 79 this->m_array = new T[obj.m_length]; 80 if(this->m_array != NULL) 81 { 82 this->m_length = obj.m_length; 83 for(int i=0; i<obj.m_length; i++) 84 { 85 this->m_array[i] = obj.m_array[i]; 86 } 87 } 88 else 89 { 90 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create DynamicArray object ..."); 91 } 92 */ 93 } 94 95 DynamicArray<T>& operator= (const DynamicArray<T>& obj) // O(n) 96 { 97 if( this != &obj ) 98 { 99 update(copy(obj.m_array, obj.m_length, obj.m_length), obj.m_length); 100 /* 101 T* array = new T[obj.m_length]; // 改写到这里 102 if( array != NULL ) 103 { 104 for(int i=0; i<obj.m_length; i++) 105 { 106 //this->m_array[i] = obj.m_array[i]; 107 array[i] = obj.m_array[i]; 108 } 109 T* temp = this->m_array; 110 this->m_array = array; 111 this->m_length = obj.m_length; 112 delete[] temp; 113 } 114 else 115 { 116 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create DynamicArray object ..."); 117 } 118 */ 119 } 120 121 return *this; 122 } 123 124 void resize( int length ) // O(n) 125 { 126 if( length != m_length) 127 { 128 update(copy(this->m_array, this->m_length, length), length); 129 /* 130 T* array = new T[length]; 131 if( array != NULL ) 132 { 133 int size = (length < m_length) ? length : m_length; 134 for(int i=0; i<size; i++) 135 { 136 array[i] = this->m_array[i]; 137 } 138 T* temp = this->m_array; 139 this->m_array = array; 140 this->m_length = length; 141 delete[] temp; 142 } 143 else 144 { 145 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to resize object ..."); 146 } 147 */ 148 } 149 } 150 151 int length() const // O(1) 152 { 153 return m_length; 154 } 155 156 ~DynamicArray() // O(1) 157 { 158 delete[] this->m_array; 159 } 160 }; 161 162 } 163 164 #endif // DYNAMICARRAY_H
6,DynamicArray 类中的函数实现存在重复的逻辑,如何进行代码优化(优化见本文 5 中的实现)?
1,init,对象构造时的初始化操作;
2,copy,在堆空间中申请新的内存,并执行拷贝操作;
3,update,将指定的堆空间作为内部存储数组使用;
7,实现代码优化中:
1,重复代码抽象为保护成员函数;
2,提供功能用于实现公有函数功能;
8,小结:
1,StaticArray 通过封装原生数组的方式实现数组类;
2,DynamicArray 动态申请堆空间,使得数组长度动态可变;
3,数组对象能够代替原生数组,并且使用上更安全;
4,代码优化是项目开发过程中不可或缺的环节:
1,每一个函数足够小;
2,每一个函数只做一件事;