觸發條件ios
- 長時間使用單鏈表對象頻繁增長和刪除元素
可能的結果編程
- 堆空間產生內存碎片,致使系統運行緩慢
在「單鏈表」的內部增長一片預留的空間,全部的Node對象都在這片空間中動態建立和動態銷燬ide
- 經過類模板定義靜態單鏈表(StaticLinkList)
- 在類中定義固定大小的空間(unsigned char[])
- 重寫 create 和 destroy 函數,改變內存的分配和歸還方式
- 在 Node 類中重載 operator new,用於在指定內存上建立對象
文件:StaticLinkList.h函數
#ifndef STATICLINKLIST_H #define STATICLINKLIST_H #include "LinkList.h" #include <iostream> using namespace std; namespace DTLib { template <typename T, int N> class StaticLinkList : public LinkList<T> { public: StaticLinkList() // O(n) { for (int i=0; i<N; ++i) { m_used[i] = 0; } } int capacity() // O(1) { return N; } protected: //typedef typename LinkList<T>::Node Node; using Node = typename LinkList<T>::Node; struct SNode : public Node { void *operator new (unsigned int size, void *loc) { (void)size; return loc; } }; unsigned char m_space[N * sizeof(SNode)]; char m_used[N]; Node *create() override // O(n) { SNode *ret = nullptr; for (int i=0; i<N; ++i) { if (m_used[i] == 0) { ret = reinterpret_cast<SNode*>(m_space) + i; ret = new(ret)SNode; m_used[i] = 1; break; } } return ret; } void destroy(Node *pn) override // O(n) { SNode *space = reinterpret_cast<SNode*>(m_space); SNode *psn = dynamic_cast<SNode*>(pn); for (int i=0; i<N; ++i) { if (psn == (space + i)) { m_used[i] = 0; pn->~Node(); break; } } } }; } #endif // STATICLINKLIST_H
文件:main.cppspa
#include <iostream> #include "StaticLinkList.h" using namespace std; using namespace DTLib; int main() { cout << "main begin" << endl; StaticLinkList<int, 5> list; for (int i=0; i<5; ++i) { list.insert(0, i); } for (list.move(0); !list.end(); list.next()) { cout << list.current() << endl; } cout << "main end" << endl; return 0; }
輸出:設計
main begin 4 3 2 1 0 main end
LinkList 中封裝 create 和 destroy 函數的意義是什麼呢?
爲靜態單鏈表(StaticLinkList)的實現準備。
StaticLinkList 與 LinkList 的不一樣僅在於鏈表節點內存分配上的不一樣;所以將僅有的不一樣封裝於父類和子類的虛函數中。3d
- 順序表與單鏈表相結合後衍生出靜態單鏈表
- 靜態單鏈表是LinkList的子類,擁有單鏈表的全部操做
- 靜態單鏈表在預留的空間中建立節點對象
- 靜態單鏈表適合於頻繁增刪元素的場合(最大元素個數固定)
以上內容整理於狄泰軟件學院系列課程,請你們保護原創!code