码迷,mamicode.com
首页 > 其他好文 > 详细

2.3 动态空间管理

时间:2018-06-17 22:27:45      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:pen   col   向量空间   必须   temp   参与   ali   之间   i++   

空间管理方法主要分为两类:静态的和动态的。顾名思义,静态空间管理即是在向量生命期内,其内部数组所占物理空间的容量不允许增加,这种策略既拘泥固化且空间管理效率底下,因此常采取动态空间管理策略,具体方法是使向量可扩充。
 
可扩充向量既能够在空间不足达到上溢临界点时扩充向量空间,同时能够在空间需求不甚强烈,达到下溢临界点时缩容空间向量。
 
扩容
 
对向量实现扩容的难点在于如何实现扩容?新的容量取作多少才算适宜?
 
如何扩容?——先保留,再扩容,后迁移。
 
因为向量是寻秩访问,上下秩之间物理地址连续,所以在扩容的过程中必须保证物理空间必须地址连续,所以可行的方法是:通过申请更大容量的内部数组,将原先内部数组中的成员集体搬迁到新的空间,此后方可顺利地插入新元素e而不致数据溢出。原数组所占空间及时释放,并归还操作系统。实现代码如下:
 
                            template <typename T> void Vector<T>::expand() {
       if (_size < _capacity)
               return;
       if (_capacity < DEFAYLT_CAPACITY)
               _capacity = DEFAYLT_CAPACITY;//使其不小于默认容量即最小容量
       T* oldElem = _elem;
       _elem = new T[_capacity <<= 1];//容量加倍
       for (int i = 0; i < _size; i++)
               _elem[i] = oldElem[i];//复制原向量内容
       delete[] oldElem;
 
}
 
有趣的是,最调用insert()接口插入新元素之前,都要先调用该算法用于检查数组容量。
 
缩容
 
当向量的规模远远小于内部数组的容量,称为下溢时,我们会采取缩容操作。具体算法如下:
 
template <typename T> void Vector<T>::shrink() {
       if (_capacity < DEFAYLT_CAPACITY << )
               return;
       if (_size << 2 > _capacity)
               return;
       T* oldElem = _elem;
       _elem = new T[_capacity >>= 1];//容量加倍
       for (int i = 0; i < _size; i++)
               _elem[i] = oldElem[i];//复制原向量内容
       delete[] oldElem;
}
 
当我们分析通过直接扩容两倍的方式来分析扩容向量复杂度时,采取的具体尺度是分摊复杂度。
 
所谓分摊复杂度和相关的分摊运行时间,其参与分摊的操作必须构成和来自一个真实可行的操作序列,且足够长。这与传统的平均运行时间有着本质的区别,后者是按照某种假定的概率分布,对各种情况下所需执行时间的加权平均,亦称期望运行时间。
 
对于本文中所采取的两倍扩容操作,所需时间为O(n)。
 
 

2.3 动态空间管理

标签:pen   col   向量空间   必须   temp   参与   ali   之间   i++   

原文地址:https://www.cnblogs.com/NK-007/p/9193759.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!