单链表的一个缺陷:
触发条件:长时间使用单链表对象频繁增加和删除数据元素。
可能的结果:堆空间产生大量的内存碎片,导致系统运行缓慢。
新的线性表:设计思路:在“单链表”的内部增加一片预留的空间,所有的Node对象都在这片空间中动态创建和动态销毁。
顺序表+单链表=静态单链表
实现思路:通过模板定义静态单链表类(StaticLinkList),在类中定义固定大小的空间(unsigned char []),重写create和destroy函数,改变内存的分配和归还方式,在Node类中重载operator new,用于在指定内存上创建对象。
#ifndef STATICLINKLIST_H_
#define STATICLINKLIST_H_
#include "LinkList.h"
namespace WSlib
{
template<typename T,int N>
class StaticLinkList:public LinkList<T>
{
protected:
typedef typename LinkList<T>::Node Node; //给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];
//因为父类中Node跟泛指类型T牵扯了关系,所以不能直接用Node,而应该指明是父类中的Node,然而还不能用,因为编译器在编译当前头文件的时候并不知道通过类名作用域分辨符访问的Node究竟是类型还是静态成员变量,编译器不能判断,所以需要通过typename指明类型,通过typedef化简
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;
//仅仅是分配内存,并没有构造函数的调用,但是如果Node里边的T是自定义类类型时, 还不能调用T value的构造函数,在指定内存上调用构造函数,所以还需要重载new操作符
ret=new(ret)SNode(); //(ret)括号表示在ret内存空间上调用构造函数m_used[i]=1;
break;
}
}
return ret;
}
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(pn == (space+i)) //第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
/*****************************************************************
#include <iostream>
#include "StaticLinkList.h"
using namespace WSlib;
using namespace std;
int main()
{
StaticLinkList<int, 5> list;
for(int i=0;i<5;i++)
{
list.insert(0,i);
}
try
{
list.insert(6);
}
catch(const Exception& e)
{
cout<<e.message()<<endl;
}
for(list.move(0);!list.end();list.next()) //O(n)
{
cout<<list.current()<<endl;
}
// 在使用单链表的地方都可以使用静态单链表
return 0;
}
******************************************************************/
小结:顺序表与单链表相结合后衍生出静态单链表,静态单链表是LinkList的子类,拥有单链表的所有操作,静态单链表在预留的空间中创建结点对象,静态单链表适合于频繁增删数据元素的场合(最大元素个数固定)