25、静态单链表的实现

单链表的一个缺陷:

触发条件:长时间使用单链表对象频繁增加和删除数据元素。

可能的结果:堆空间产生大量的内存碎片,导致系统运行缓慢。

新的线性表:设计思路:在“单链表”的内部增加一片预留的空间,所有的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的子类,拥有单链表的所有操作,静态单链表在预留的空间中创建结点对象,静态单链表适合于频繁增删数据元素的场合(最大元素个数固定)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值