之前我们说过如果频繁增删数据元素,我们应该选择单链表就可以,但是如果数据元素的最大个数固定,那么就需要静态单链表,而且动态单链表如果长时间使用单链表对象频繁增加和删除数据元素,堆空间产生大量的内存碎片,导致系统运行缓慢,所谓单链表就是“顺序表 + 单链表 =静态单链表”
设计思路
在"单链表"的内部增加一片预留的空间,所有的Node对象都在这片空间中动态创建和动态销毁,所以我们得重载create()和destory()改变内存的分配和归还方式,重载operator new,用于在指定内存上创建对象,我就仅需要将StaticLinkList继承于Linklist即可,
#ifndef STATICLINKLIST_H
#define STATICLINKLIST_H
#include "LinkList.h"
namespace CGSLib
{
template<typename T ,int N>
class StaticLinkList : public LinkList<T>
{
protected:
typedef typename LinkList<T>::Node Node;
struct SNode:public Node
{
void* operator new(unsigned int size,void* loc)
{
return loc;
}
};
unsigned char m_space[sizeof(Node)*N];
int m_used[N];
Node* create()
{
SNode* ret =NULL;
for(int i=0;i<N;i++)
{
if(!m_used[i])
{
ret = reinterpret_cast<SNode*>(m_space)+i;
ret = new(ret)SNode();
m_used[i] = 1;
break;
}
}
return ret;
}
void destory(Node* pn)
{
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;
psn->~SNode();
}
}
}
public:
StaticLinkList()
{
for(int i=0;i<N;i++)
{
m_used[i] = 0;
}
}
int capacity()
{
return N;
}
};
};
#endif // STATICLINKLIST_H
LinkList中封装create和destroy函数的意义为静态单链表(StaticLinkList)的实现做准备,StaticLinkList与LinkList的不同仅在于链表结点内存分配上的不同,因此,将仅有的不同封装于父类和子类的虚函数中,