template <typename T> class SqlList : public List<T> { public: bool insert(int i, const T &e); // O(n) bool remove(int i); // O(n) bool set(int i, const T &e); // O(1) bool get(int i, T &e) const; // O(1) int length() const; // O(1) void clear(); // O(1) T &operator[] (int i); // O(1) T operator[] (int i) const; // O(1) virtual int capacity() const = 0; };
長度相同的兩個 SqlList, 插入和刪除操做的平均耗時是否相同?
不必定,須要具體狀況具體分析。
例:算法
SqlList<string> ss; SqlList<string> si; ss.insert(0, "D.T.Software"); si.insert(0, 1);
SqlList中,最耗時的是插入和刪除操做,由於要進行移位,尤爲當數據元素是自定義類類型,而且類很是龐大時耗時尤其明顯。
所以,分析一段代碼的效率,不可以只看時間複雜度(大O表示法),大O表示法僅爲參考指標,而非絕對指標。還須要具體狀況具體分析,當前算法是否真的知足需求。
由此也證實順序存儲表不適合類類型的元素存儲,適合基本類型。數組
StaticList<int*, 5> s1; StaticList<int*, 5> s2; for (int i=0; i<s1.capacity(); ++i) { s1.insert(0, new int(i)); } s2 = s1; // 注意 1 for (int i=0; i<s1.length(); ++i) { delete s1[i]; // 注意 2 delete s2[i]; }
不正確。
注意 1:兩鏈表中對應兩元素指向同一堆空間
注意 2:內存被釋放兩次,行爲未定義函數
void func() { DynamicList<int> d1(5); DynamicList<int> d2 = d1; // 注意 1 for (int i=0; i<d1.capacity(); ++i) { d1.insert(i, i); // 注意 2 d2.insert(i, i*i); // 注意 2 } for (int i=0; i<d1.lenth(); ++i) { cout >> d1[i] << endl; } }
不正確。
注意 1: 兩鏈表中對應兩元素指向同一堆空間
注意 2: d1中插入的數據被重寫
注意 3: 對象析構時,同一堆空間被釋放兩次spa
- 分析:對於容器類型的類,能夠考慮禁用拷貝構造和賦值操做.
template <typename T> class List : public Object { protected: List(const List&); List &operator= (const List&); public: List() { } // ... };
課程中的解釋:面向對象是將生活中的概念平行搬移到程序設計中,而生活中沒法完成兩個容器的拷貝動做。設計
文件:List.hcode
#ifndef LIST_H #define LIST_H #include "Object.h" namespace DTLib { template<typename T> class List : public Object { public: List() {} virtual bool insert(int i, const T &e) = 0; virtual bool remove(int i) = 0; virtual bool set(int i, const T &e) = 0; virtual bool get(int i, T &e) const = 0; virtual int length() const = 0; virtual void clear() = 0; protected: List(const List&); List<T> &operator= (const List&); }; } #endif // LIST_H
int main() { StaticList<int, 5> list; for (int i=0; i<list.capacity(); ++i) { list[i] = i * i; } return 0; }
不正確。
在 [] 數組操做符重載函數中可見, m_length 爲 0, 下表合法性檢查沒法經過,拋出異常對象
順序存儲結構線性表提供了數組操做符重載,經過重載可以快捷方便的獲取目標位置處的數據元素,在具體的使用形式上相似數組,但因爲本質不一樣,不能代替數組使用。blog
- 線性表必須先插入元素,才能使用操做符 [] 訪問元素
- 順序存儲線性表的插入和刪除操做存在重在效率隱患
- 線性表做爲容器,應該避免拷貝構造和拷貝賦值
- 順序存儲線性表可能被當成數組誤用
- 工程開發中能夠考慮使用數組類代替原生數組使用
以上內容整理於狄泰軟件學院系列課程,請你們保護原創!內存