数据结构中的数组——动态数组的创建

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,每一个函数只做一件事;

posted @ 2019-05-25 11:04  子宇24  阅读(1270)  评论(0编辑  收藏  举报