2.3 動態空間管理
阿新 • • 發佈:2018-06-18
動態空間 操作系統 nbsp 強烈 系統 期望 sun cto 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 動態空間管理