数据结构之链表

1.链表的特点

特点:

1.数据分散存储

2.查询性能没有Vector好

3.新增与删除性能好于Vector

2.链表的种类

3.链表的实现

#include<stdio.h>
#include<Windows.h>


#define SUCCESS           1 // 执行成功										
#define ERROR            -1 // 执行失败										
#define INDEX_IS_ERROR   -2 // 错误的索引号										
#define BUFFER_IS_EMPTY  -3 // 缓冲区已空										
										
										
template <class T_ELE>										
class LinkedList										
{										
public:										
	LinkedList();									
	~LinkedList();									
public:										
	BOOL  IsEmpty();						//判断链表是否为空 空返回1 非空返回0			
	void  Clear();						//清空链表			
	DWORD GetElement(IN DWORD dwIndex,OUT T_ELE& Element);						//根据索引获取元素			
	DWORD GetElementIndex(IN T_ELE Element);						//根据元素获取链表中的索引			
	DWORD Insert(IN T_ELE Element);						//新增元素			
	DWORD Insert(IN DWORD dwIndex, IN T_ELE Element);						//根据索引新增元素			
	DWORD Delete(IN DWORD dwIndex);						//根据索引删除元素			
	DWORD GetSize();						//获取链表中元素的数量	
private:										
	typedef struct _NODE 									
	{									
		T_ELE  Data;								
		_NODE *pNext;								
	}NODE,*PNODE;									
	PNODE GetIndexCurrentNode(DWORD dwIndex);						//获取索引为dwIndex的指针			
	PNODE GetIndexPreviousNode(DWORD dwIndex);						//获取索引为dwIndex的前一个节点指针			
	PNODE GetIndexNextNode(DWORD dwIndex);						//获取索引为dwIndex的后一个节点指针			
private:										
	PNODE m_pList;						//链表头指针,指向第一个节点			
	DWORD m_dwLength;						//元素的数量			
};										
										
//无参构造函数 初始化成员										
template<class T_ELE> LinkedList<T_ELE>::LinkedList()										
:m_pList(NULL),m_dwLength(0)									
{										
										
}										
//析构函数 清空元素										
template<class T_ELE> LinkedList<T_ELE>::~LinkedList()										
{										
	Clear();									
}										
//判断链表是否为空										
template<class T_ELE> BOOL LinkedList<T_ELE>::IsEmpty()										
{										
	if(m_pList==NULL || m_dwLength==0)
		return true;
	else
		return false;			
}										
//清空链表										
template<class T_ELE> void LinkedList<T_ELE>::Clear()										
{										
	// 1. 判断链表是否为空									
	if(m_pList!=NULL)
	{
		
	// 2. 循环删除链表中的节点		
		PNODE tmpListp=m_pList;
		for(int i=0;i<m_dwLength;i++)
		{
			delete tmpListp;
			tmpListp=tmpListp->pNext;
		}
	// 3. 删除最后一个节点并将链表长度置为0									
		m_dwLength=0;
	}
}										
//根据索引获取元素										
template<class T_ELE> DWORD LinkedList<T_ELE>::GetElement(IN DWORD dwIndex,OUT T_ELE& Element)										
{										
	// 1. 判断索引是否有效									
	if(dwIndex<0 || dwIndex>=m_dwLength)
	{
		return INDEX_IS_ERROR;
	}
	// 2. 取得索引指向的节点
	PNODE tmpListp=m_pList;
	for(int i=0;i<dwIndex;i++)
		tmpListp=tmpListp->pNext;

	// 3. 将索引指向节点的值复制到OUT参数									
	Element=tmpListp->Data;
	return Element;
}										
//根据元素内容获取索引										
template<class T_ELE> DWORD LinkedList<T_ELE>::GetElementIndex(IN T_ELE Element)										
{										
	// 1. 判断链表是否为空									
	if(m_pList==NULL || m_dwLength==0)
		return BUFFER_IS_EMPTY;										

	// 2. 循环遍历链表,找到与Element相同的元素	
	PNODE tmpListp=m_pList;
	for(int i=0;i<m_dwLength;i++)
	{
		if(memcmp(&tmpListp->Data,&Element,sizeof(T_ELE))==0)
			return i;
		tmpListp=tmpListp->pNext;
	}
	return ERROR;
									
}	

//在链表尾部新增节点										
template<class T_ELE> DWORD LinkedList<T_ELE>::Insert(IN T_ELE Element)										
{		
	PNODE newNodep=new NODE;
	memset(newNodep,0,sizeof(NODE));
	memcpy(&newNodep->Data,&Element,sizeof(T_ELE));

	// 1. 判断链表是否为空									
	if(m_pList==NULL || m_dwLength==0)
	{
		m_pList=newNodep;//修改指针
		m_dwLength++;//修改长度
		return SUCCESS;
	}
	// 2. 如果链表中已经有元素	
	PNODE tmpNodep=m_pList;
	for(int i=0;i<m_dwLength-1;i++)
		tmpNodep=tmpNodep->pNext;

	tmpNodep->pNext=newNodep;
	m_dwLength++;

	return SUCCESS;
}										
//将节点新增到指定索引的位置						0 1 2 3 4				
template<class T_ELE> DWORD LinkedList<T_ELE>::Insert(IN DWORD dwIndex, IN T_ELE Element)										
{										
	PNODE newNodep=new NODE;
	memset(newNodep,0,sizeof(NODE));
	memcpy(&newNodep->Data,&Element,sizeof(T_ELE));									
	//  1. 判断链表是否为空									
	if(m_pList==NULL || m_dwLength==0)
	{
		if(dwIndex==0)     //在链表为空的情况下,索引不为0就是索引错误
		{
			m_pList=newNodep;//修改指针
			m_dwLength++;//修改长度
			return SUCCESS;
		}
		else
			return INDEX_IS_ERROR;
	}									
	//  2. 判断索引值是否有效									
	if(dwIndex<0 || dwIndex>=m_dwLength)
		return INDEX_IS_ERROR;
	//  3. 如果索引为0									
	if(deIndex==0)
	{
		PNODE tmpListp=m_pList;
		tmpListp=tmpListp->pNext;//获得第二节点地址

		m_pList=newNodep;
		m_pList->pNext=tmpListp;
		m_dwLength++;
	}
	//  4. 如果索引为链表尾									
	else if(dwIndex==(m_dwLength-1))	
	{
		PNODE tmpListp=m_pList;
		while(tmpListp->pNext==0)
			tmpListp=tmpListp->pNext;//获得最后一节点的地址
	
		tmpListp->pNext=newNodep;
		m_dwLength++;
	}
	//  5. 如果索引为链表中	
	else
	{
		PNODE tmpListp=m_pList,tmpListp1;
		for(int i=0;i<dwIndex;i++)
			tmpListp=tmpListp->pNext;//  获得索引节点的地址
		for(int i=0;i<=dwIndex;i++)
			tmpListp1=tmpListp1->pNext;
		tmpListp->pNext=newNodep;
		newNodep->pNext=tmpListp;
		m_dwLength++;
	}
}										
//根据索引删除节点										
template<class T_ELE> DWORD LinkedList<T_ELE>::Delete(IN DWORD dwIndex)										
{										
	//  1. 判断链表是否为空									
	if(m_pList==0 || m_dwLength==0)
		return BUFFER_IS_EMPTY;
	
	//  2. 判断索引值是否有效									
	if(dwIndex<0 || dwIndex>=m_dwLength)
		return INDEX_IS_ERROR;
	
	//  3. 如果链表中只有头节点,且要删除头节点									
	if(m_dwLength==0)
	{
		if(dwIndex==0)
		{
			delete m_pList;
			m_pList==NULL;
			m_dwLength--;

			return SUCCESS;
		}
		else
			printf("元素不足\n");
	}
	
	//  4. 如果要删除头节点									
	else if(dwIndex==0)
	{
		m_pList=m_pList->pNext;
		delete m_pList;
			m_pList==NULL;
			m_dwLength--;
	}
	//  5. 如果是其他情况
	else if(dwIndex==m_dwLength-1)
	{
		PNODE p1=GetIndexPreviousNode(dwIndex);//得到索引前一位地址
		PNODE p2=GetIndexCurrentNode(dwIndex);//得到索引位置的地址
		p1->pNext=0;
		delete p2;
		m_dwLength--;
	}
	else
	{
		PNODE p1=GetIndexPreviousNode(dwIndex);//得到索引前一位地址
		PNODE p2=GetIndexCurrentNode(dwIndex);//得到索引位置的地址
		//PNODE p3=GetIndexNextNode(dwIndex);//得到索引后一位的地址	
		p1->pNext=p2->pNext;
		delete p2;
		m_dwLength--;
		return SUCCESS;
	}
}					
					
//获取链表中节点的数量										
template<class T_ELE> DWORD LinkedList<T_ELE>::GetSize()										
{										
	return m_dwLength;									
}		
								
//获取dwIndex前面节点的地址										
template<class T_ELE> 										
LinkedList<T_ELE>::PNODE LinkedList<T_ELE>::GetIndexPreviousNode(DWORD dwIndex)										
{										
	// 就是一个循环	
	PNODE tmpListp=m_pList;
	for(int i=0;i<dwIndex-1;i++)
			tmpListp=tmpListp->pNext;

	return tmpListp;
										
}										
//获取dwIndex节点的地址										
template<class T_ELE> 										
LinkedList<T_ELE>::PNODE LinkedList<T_ELE>::GetIndexCurrentNode(DWORD dwIndex)										
{										
	// 就是一个循环									
	PNODE tmpListp=m_pList;
	for(int i=0;i<dwIndex;i++)
			tmpListp=tmpListp->pNext;

	return tmpListp;									
}										
//获取dwIndex后面节点的地址										
template<class T_ELE> 										
LinkedList<T_ELE>::PNODE LinkedList<T_ELE>::GetIndexNextNode(DWORD dwIndex)										
{										
	// 就是一个循环									
	PNODE tmpListp=m_pList;
	for(int i=0;i<dwIndex+1;i++)
			tmpListp=tmpListp->pNext;

	return tmpListp;									
}										

void Test()
{
	LinkedList<int>* lin=new LinkedList<int>;
	lin->Insert(1);
	lin->Insert(2);
	lin->Insert(3);
	lin->Insert(4);

	//lin->Clear();
	//int x=lin->GetElement(2,x);
	//printf("%d\n",x);
	//lin->Delete(3);
	int i=lin->GetElementIndex(4);
	printf("索引是:%d\n",i);
	
}

int main()
{
	Test();

	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值