#pragma once
/**
*原理很简单,将数组的元素看成是链表,或者说是数组空间起到了内存池的作用。然后用两个结点表示
*当前使用/空闲的链表
*
*对效率问题上的一些说明
*增:这个无需说,链表直接秒杀。
*删:类里提供的是一个ELEMENT结构,里面包含了用户的数据。如果你想保持常量的效率
*在一些数据接口提供是,也必须用ELEMENT,这样才能记住结点信息。否则你可以单开个你自己数据类型的接口
*但是在删除时,就必须遍历(删除方法见提供的实例)
*ELEMENT类型的快速使用:typedef CListWithArray<int,1000>::ELEMENT CListWithArray_t;
*你维护好CListWithArray_t就行
*提供以下接口
* bool Add(llist_t* e); //返回一个表示是否插入成功的标志。
* llist_t* Erase(); //取的结点的下一个元素,并且原链表中删除
* 将next提供给使用者,无需太多的其他接口,可以满足大部分要求
**/
namespace list_with_array
{
template<typename llist_t, int llist_size=100>
class CListWithArray
{
//variable
public:
struct ELEMENT
{
llist_t element;
ELEMENT* pPre;
ELEMENT* pNext;
};
private:
ELEMENT elementData[llist_size];//数组空间
ELEMENT freeElement; //空余的指针链头
ELEMENT useElement; //当前使用的指针链头
//function
public:
CListWithArray();
bool Add(const llist_t e);
ELEMENT* Erase(ELEMENT *p)
{
return ReleaseElement(p);
}
ELEMENT* GetListHead()
{
return useElement.pNext;
}
/**
*信息的一些监控
**/
int GetSumUseElement()
{
int sum=0;
ELEMENT* p;
for(p=useElement.pNext; p!=NULL; p=p->pNext)
{
++sum;
}
return sum;
}
int GetSumFreeElement()
{
int sum=0;
ELEMENT* p;
for(p=freeElement.pNext; p!=NULL; p=p->pNext)
{
++sum;
}
return sum;
}
private:
/**
*初始链表串,双指针链表
**/
void InitList();
ELEMENT* MallocElement();
ELEMENT* ReleaseElement(ELEMENT *p);
/**
*将一个结点加入到目的链表
**/
void AddNodeToList(ELEMENT* const pNode, ELEMENT* const pDesList)
{
//处理好结点头尾
pNode->pNext = pDesList->pNext;
pNode->pPre = pDesList;
//判断是否已经有元素,以便前置变量的赋值
if( NULL!=pDesList->pNext )
{
pDesList->pNext->pPre = pNode;
}
pDesList->pNext = pNode;
}
};
/**
*这里是大函数体定义
**/
template <typename llist_t, int llist_size>
CListWithArray<llist_t, llist_size>::CListWithArray()
{
InitList();
}
template <typename llist_t, int llist_size>
void CListWithArray<llist_t, llist_size>::InitList()
{
//开始串指针
for(int i=0; i<llist_size-1; ++i)
{
elementData[i].pNext = &elementData[i+1];
}
elementData[llist_size-1].pNext = NULL;
useElement.pNext = NULL;
freeElement.pNext = &elementData[0];
}
template <typename llist_t, int llist_size>
typename CListWithArray<llist_t, llist_size>::ELEMENT* CListWithArray<llist_t, llist_size>::MallocElement()
{
//判断是否有空余元素
if( NULL==freeElement.pNext )
{
return NULL;
}
//从Free链中脱出,头部
ELEMENT* p = freeElement.pNext;
freeElement.pNext = freeElement.pNext->pNext;
//空运的状态
p->pPre = NULL;
p->pNext = NULL;
AddNodeToList(p, &useElement);
return p;
}
template <typename llist_t, int llist_size>
typename CListWithArray<llist_t, llist_size>::ELEMENT* CListWithArray<llist_t, llist_size>::ReleaseElement( ELEMENT *p)
{
ELEMENT *pResult = p->pNext;
//从Use链中脱离
p->pPre->pNext = p->pNext;
//判断是否是尾元素
if( NULL!=p->pNext )
{
p->pNext->pPre = p->pPre;
}
//空运状态
p->pPre = NULL;
p->pNext = NULL;
AddNodeToList(p, &freeElement);
return pResult;
}
template <typename llist_t, int llist_size>
bool CListWithArray<llist_t, llist_size>::Add(const llist_t e)
{
//先从Free指针里取得一个空节点
ELEMENT *p = MallocElement();
if( NULL==p )
{
return false;
}
else
{
p->element = e;
return true;
}
}
};
/*
使用方法
#include "CListWithArray.h"
using namespace std;
using namespace list_with_array;
CListWithArray<int,1000> listTest;
typedef CListWithArray<int,1000>::ELEMENT CListWithArray_t;
void cout_listinfo()
{
cout<<"sum use:"<<listTest.GetSumUseElement()<<endl;
cout<<"sum free:"<<listTest.GetSumFreeElement()<<endl;
cout<<"-------------------"<<endl;
}
void test_del_1()
{
CListWithArray_t *p=listTest.GetListHead();
while( NULL!=p )
{
if( ((p->element)&0x1) == 0 ) //删掉奇数
{
p = listTest.Erase(p); //注意,这里p的信息已经被修改,无需再p->pNext;
continue;
}
p=p->pNext;
}
}
void test_del_2()
{
CListWithArray_t *p=listTest.GetListHead();
while( NULL!=p )
{
if( 1000==p->element || 2000==p->element )
{
p = listTest.Erase(p);
continue;
}
p=p->pNext;
}
}
void test_add_1()
{
for(int i=0; i<1100; ++i)
{
listTest.Add(i);
}
}
void test_add_2()
{
for(int i=0; i<3; ++i)
{
listTest.Add(i*1000);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
cout_listinfo(); //链表最早状态
test_add_1(); //加满链表
cout_listinfo();
test_del_1(); //删除奇数
cout_listinfo();
test_add_2(); //压入个特殊数,0,1000,2000
cout_listinfo();
test_del_2(); //删除1000,2000
cout_listinfo();
return 0;
}
*/
数组模拟链表的实现
最新推荐文章于 2020-04-08 21:34:41 发布