1. 实现一个动态数组,要求对于随机访问可以在常数时间完成,可以通过push_back向数据的尾部追加元素,可以通过pop_back删除尾部元素,能够满足常见的数组操作。 LINE 2016年春招笔试

 

这里说的动态数组是可以根据需要动态增长占用内存的数组,比如程序初始分配了100个元素,可是运行了一段时间后区区100个空间不能满足了,现在需要400个,怎么办呢;那肯定需要再额外分配300个。

C语言有realloc()函数来解决空间扩充的问题,但是不要忘了realloc可能会迁移内存,会发现数据要复制

C++中的vector和这个题的要求很像,但是vector在扩展内存的时候,也是要复制数据

一次分配足够的空间是可以解决这个问题,很明显这会造成内存的浪费,这个做法不算明智。

不使用数组呢?使用list能解决一部分问题,但是list不能支持随机访问啊,鉴于效率上的硬伤,显然不能随便用list替换数组。

 

怎么解决这个问题呢?动态数组

动态数组的特征

动态数组是一个很简单易用的数据结构,但是简单不代表优点小,它的特征如下:

1 根据需要动态批量增长内存;

2 一经分配,元素地址不会再次变化;

3 实现简单,效率高,事实上它和普通数组相比基本没有效率损失;

4 最大个数固定;

其实最重要的就是特征2了,不然直接使用realloc多方便呢,当然动态数组的实现也很方便

 

#include<iostream>

using namespace std;

//动态数组,最多200个单位,空间不够的时候,一次自动增长10个单位 ,所以capacity是size的最接近10的数

class DArray

{

    public:

        int* section[20];

        int size;//动态数组的实际大小

        int capacity;//动态数组最多能容纳多少    

        DArray(int sizep)//指定动态数组大小,并初始化成0

        {

            if(sizep<=200)

            {

                int time=0;

                if(size%10==0)//如果size是30的话,最大的数保存到29,就是0 1 2 三个数组

                {

                    time=sizep/10-1;

                    capacity=size;

                }                    

                else

                {

                    time=sizep/10;

                    capacity=(time+1)*10;

                }

                    

                for(int i=0; i<=time; i++)//多初始化一些也没有关系

                {

                 section[i]=new int[10];    

                 for(int j=0;j<10;j++)

                 section[i][j]=0;

                }

                 

                size=sizep;    

            }

            else

                cout<<"无法分配超过200的空间!"<<endl;

 

        }

 

        int& operator[](int index)//重载方括号

        {

            int sec=index/10;

            int offset=index%10;

            return section[sec][offset];

        } //A reference shall be initialized to refer to a valid object or function.

 

        int resize(int newSize)//重新分配数组大小,如果newSize>size,则用0填充

        {

            if(newSize<=200)

            {

                if(newSize<=capacity)//现在还是装的下的

                {

                    if(size<newSize)//从小到大是 size newSize capacity

                     for(int i=size;i<newSize;i++)

                     section[size/10][i%10]=0;

                                                        

                }

                else

                {//这样的话从小到大就是 size capacity newSize

                    for(int i=size;i<capacity;i++)

                     section[size/10][i%10]=0;

                    while(capacity<newSize)//多初始化一些,没有关系

                    {

                        section[capacity/10]=new int[10];

                        for(int i=0;i<10;i++)

                         section[capacity/10][i]=0;

                        capacity+=10;

                    }                    

                }

                size=newSize;

 

 

            }

            else

             return 0;

        }

 

        void push_back(int ele)

        {

         if(size<=199)

         {

                 

            if(size==capacity)//需要扩容

            {

                section[capacity/10]=new int[10];

                capacity+=10;

 

            }

            section[size/10][size%10]=ele;

            size++;

         }

         else

         cout<<"已满!"<<endl;

        }

 

        void pop_back()

        {

            size--;

        }

 

        ~DArray()

        {

            while(capacity>0)

            {

                delete [] section[capacity/10-1];

                capacity-=10;

            }

            cout<<"已经析构!"<<endl;

 

        }

 

};

 

int main()//测试动态数组

{

    DArray array(2);

    for(int i=0; i<24; i++)

    {

        array.push_back(i);

    }

    for(int i=0;i<array.size;i++)

    {

        cout<<array[i]<<" ";

    }

    cout<<endl;

    cout<<"size: "<<array.size<<" capacity: "<<array.capacity<<endl;

    array.resize(35);

        for(int i=0;i<array.size;i++)

    {

        cout<<array[i]<<" ";

    }

    cout<<endl;

    cout<<"size: "<<array.size<<" capacity: "<<array.capacity<<endl;

//    array

    
 

    

}

动态数组结构如下:

 

0

1

2

3

4

     

9

capacity

0

               

9

10

1

               

19

20

2

               

29

30

3

               

39

40

4

               

49

50

 

 

思路来自 http://blog.csdn.net/sparkliang/article/details/5359634

C++实现动态数组的更多相关文章

  1. 常用数据结构-线性表及Java 动态数组 深究

    [Java心得总结六]Java容器中——Collection在前面自己总结的一篇博文中对Collection的框架结构做了整理,这里深究一下Java中list的实现方式 1.动态数组 In compu ...

  2. C语言 · 动态数组的使用

    从键盘读入n个整数,使用动态数组存储所读入的整数,并计算它们的和与平均值分别输出.要求尽可能使用函数实现程序代码.平均值为小数的只保留其整数部分. 样例输入: 5 3 4 0 0 2样例输出:9 1样 ...

  3. C++中关于[]静态数组和new分配的动态数组的区别分析

    这篇文章主要介绍了C++中关于[]静态数组和new分配的动态数组的区别分析,很重要的概念,需要的朋友可以参考下 本文以实例分析了C++语言中关于[]静态数组和new分配的动态数组的区别,可以帮助大家加 ...

  4. C++之动态数组

    C99支持一种名为变长数组的结构来方便程序员.C++也提供了一种长度可在程序运行时确定的数组类型:动态数组.声明格式为:(声明 int 类型的数组) ; //此处可修改 ArraySize 的值 in ...

  5. VB默认属性、动态数组、Range对象的默认属性的一点不成熟的想法

    1.默认属性 VB6.0有默认属性的特性.当没有给对象指定具体的属性时,"默认属性"是VB6.0将使用的属性.在某些情形下,省略常用属性名,使代码更为精简. 因为CommandBu ...

  6. C#有关数组内存的释放及动态数组问题

    一.数组内存释放问题 数组内存的释放可以按照如下语句实现: string [] aa=new string[2]; aa[0]="A"; aa[1]="B"; ...

  7. (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)

    目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...

  8. C++ 动态数组实例

    一维动态数组的实例: #include <iostream> using namespace std; int main() { int *arr; int n; cout<< ...

  9. C++动态数组

    一: 一维数组初始化 标准方式1:int value[100]; //value[i]的值不定,因为没有初始化:标准方式2:int value[100] = {1,2,3}; //value[0],v ...

  10. ALLOCATE语句分配FORTRAN动态数组方法(转自http://blog.csdn.net/zhuxianjianqi/article/details/8067174)

    数组的动态分配 a)    可分配数组 数组可以是静态的也可以是动态的.如果数组是静态的,则在编译时就被分配了固定的储存空间,并且直到程序退出时才被释放.程序运行时静态数组的大小不能改变.静态数组的缺 ...

随机推荐

  1. Mike and distribution

    题意: 给定 $n$ 个物品,每个物品有两个属性$a_i$, $b_i$,求一个长度为$[\frac{n}{2}]+1$的子序列 $p$ 使得 $2 * \sum_{i = 1}^{|p|}{a_{p ...

  2. 5 手写Java Stack 核心源码

    Stack是Java中常用的数据结构之一,Stack具有"后进先出(LIFO)"的性质. 只能在一端进行插入或者删除,即压栈与出栈 栈的实现比较简单,性质也简单.可以用一个数组来实 ...

  3. laravel MVC分布及数据库配置

    laravel MVC分布 M app\Http\Middleware V resources\views C app\Http\Controllers 数据库配置 目录   config\datab ...

  4. 2014-9-9 NOIP模拟赛

    东方幻想乡系列模拟赛Stage 1命题 Nettle审题 Barty ccy1991911 FlanS39 Wagner T2 高精除高精,从来没写过,不知道怎么写,我就用大数减小数ans次,果断超时 ...

  5. IT兄弟连 JavaWeb教程 JSTL常用标签

    1.条件标签 条件标签能够实现Java语言中的if语句以及if-else语句的功能,它包括以下几种: <c:if>:用于实现Java语言中的if语句的功能. <c:choose> ...

  6. ubuntu 14.04 源码编译mysql-5.7.17

    环境为 Ubuntu 12.04 64 位的桌面版 编译的mysql 版本为 5.7.18 首先需要安装一下依赖包 sudo apt-get install libncurses5-dev cmake ...

  7. 常用SQL语句写法(一)

    <resultMap id="userResult" type="com.cloudwalk.shark.model.User"> <id p ...

  8. [Noip2012普及组]摆花

    Description 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m 盆.通过调查顾客的喜好,小明列出了顾客最喜欢的 n 种花,从 1 到 n 标号.为了在门口展出更多种花,规定 ...

  9. 开源Html5+Websocket+Mqtt实时聊天室

    本应用示例使用Coolpy7作为Mqtt服务器并启用Websocket代理完美支持高并发大流量即时通过能力,本示以即时通信聊天为为例.还可以应用到其他软件应用如:网页客服系统.网站信息通知.网页即时通 ...

  10. C# 委托之把委托从委托链(多播委托)移除

    运用“-”运算符将委托从委托链移除 class HelloWorld { //定义委托类型 delegate void DelegationChain(); static void Main(stri ...