触发条件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