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


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

  • 相关阅读:
    绿色版 notepad++ 添加鼠标右键菜单
    Scala 安装与配置
    Scala 神奇的下划线 _
    Kafka 安装部署
    Pulsar 下一代消息平台
    Sqoop 安装部署
    Flume 常用配置项
    Android-selector
    android- 9patch
    有关内存的思考题
  • 原文地址:https://www.cnblogs.com/dishengAndziyu/p/10921743.html
Copyright © 2020-2023  润新知