数组模拟链表的实现

#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;
}

*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值