单链表的一个缺陷
-触发条件
·长时间使用单链表对象频繁增加和删除数据元素
-可能的结果
·堆空间产生大量的内存碎片,导致系统运行缓慢
新的线性表
设计思路:
在单链表的内部增加一片预留的空间,所有Node对象都在这片空间中动态创建和动态销毁。
静态单链表的实现思路
-通过模板定义静态单链表类
-在类中定义固定大小的空间
-重写create和destroy函数,改变内存的分配和归还方式
-在Node类中重载operator new,用于在指定内存上创建对象
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)
{
(void)size;
return loc;
}
};
unsigned char m_space[sizeof(SNode) * N];
int m_used[N];
Node* create()
{
SNode* ret = NULL;
for(int i=0;i<N;i++)
{
if(!m_used[i])
{
if(!m_used[i])
{
ret = reinterpret_cast<SNode*>(m_space) + i;
ret = new(ret)SNode();
m_used[i] = 1;
break;
}
}
}
return ret;
return NULL;
}
void destroy(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;
}
};
LinkList中封装create和destroy函数的意义是什么?
为静态单链表(StaticLinkList)的实现做准备。StaticLinkList与LinkList的不同仅在于链表结点内存分配的不同;
因此,将仅有的不同封装与父类和子类的虚函数中
总结:
顺序表和单链表相结合后衍生出静态单链表
-静态单链表是LInkList的子类,拥有单链表的所有操作
-静态单链表在预留的空间中创建结点对象
-静态单链表适合于频繁增删数据元素的场合(最大元素个数固定)