单链表(测试)

更新

 

#include <stdlib.h>
//////////////////////////////////////////////////////////////////////////
//单链表
//////////////////////////////////////////////////////////////////////////

//链表节点
struct ListNode 
{
	void*		pData;	//要存储的数据
	ListNode*	pNext;	//执向下一个节点
};

struct OnlyList
{
	OnlyList():pHead(nullptr),nSize(0)
	{
	}
	ListNode* pHead;	//添加一个头指针,方便操作
	unsigned int nSize;			//链表节点有效个数,方便知道总共有多少个节点
};

//增加元素
////////////////////////////////////////////////////////////////////////////////////////////////////
//往链表中添加数据,默认从头插入,即头插法
//1.链表需要已经存在的
//2.数据需要已经存在的
bool AddOnlyListBeginEle(OnlyList* pList, void* pdata)
{
	//List和data任意一个为空则什么也不做
	if (pList==nullptr || pdata == nullptr)
	{
		return false;
	}
	//创建一个新的节点
	ListNode* pNode = (ListNode*)malloc(sizeof(ListNode));
	//复制数据指针变量
	pNode->pData = pdata;
	//把链表头指针赋给新节点的下一个节点的指针
	pNode->pNext = pList->pHead;
	//把新节点的指针赋给链表的头指针
	pList->pHead = pNode;
	//链表节点增加一个
	pList->nSize++;	
	return true;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

//删除元素
////////////////////////////////////////////////////////////////////////////////////////////////////
//删除链表中的首元素
bool DelOnlyListBeginEle(OnlyList* pList)
{
	if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
	{
		return false;
	}
	//临时储存链表的头指针
	ListNode* pTmp = pList->pHead;
	//把链表的头指针所指向的下一个节点指针复制链表的头指针
	pList->pHead = pTmp->pNext;
	//有效个数减一
	pList->nSize--;

	//释放空间
	//pTmp->pNext = nullptr;
	free(pTmp);
	return true;
}

//删除链表中的尾元素
bool DelOnlyListEndEle(OnlyList* pList)
{
	if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
	{
		return false;
	}
	
	ListNode* pTmpEndNode = pList->pHead;
	ListNode* pTmpPreEndNode = pTmpEndNode;
	//////////////////////////////////////////////////////////////////////////
	//找到尾结点---第一种方法---------------------------------------
	//////////////////////////////////////////////////////////////////////////
	//判断是否为空,不为空则循环,直到找到尾节点结束
	while (pTmpEndNode->pNext)	//查找节点的下一个节点指针是否为NULL
	{
		pTmpPreEndNode =  pTmpEndNode;			//存储本次循环节点,直到找到尾结点,即时尾结点的前一个节点
		pTmpEndNode   =  pTmpEndNode->pNext;	//存储本次循环节点的下一个节点指针,直到找到尾结点
	}
	//把倒数第二个下一个指针域赋值为nullptr
	pTmpPreEndNode->pNext = nullptr;
	//有效个数减一
	pList->nSize--;
	//释放尾结点空间
	free(pTmpEndNode);

	//当只有一个有效元素时
	if (pList->nSize == 0)
	{
		pList->pHead = nullptr;
	}
	//////////////////////////////////////////////////////////////////////////

	return true;
}

//在链表中删除指定索引的一个元素
bool DelOnlyListEleByIndex(OnlyList* pList,unsigned int index)		//index索引从1开始
{
	if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
	{
		return false;
	}

	ListNode* pTmpEndNode = pList->pHead;
	ListNode* pTmpPreEndNode = pTmpEndNode;
	for (unsigned int i=0; i< (index-1); i++)
	{
		pTmpPreEndNode = pTmpEndNode;
		pTmpEndNode = pTmpEndNode->pNext;
	}

	pTmpPreEndNode->pNext = pTmpEndNode->pNext;
	pList->nSize--;
	free(pTmpEndNode);

	//当只有一个有效元素时
	if (pList->nSize == 0)
	{
		pList->pHead = nullptr;
	}
	return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////

//修改元素
////////////////////////////////////////////////////////////////////////////////////////////////////
//在链表中修改指定索引的一个元素
bool UpdateOnlyListEleByIndex(OnlyList* pList,unsigned int index,void* data)		//index索引从1开始
{
	if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
	{
		return false;
	}
	if (index > (pList->nSize) || index <= 0)
	{
		return false;
	}
	ListNode* pTmpEndNode = pList->pHead;
	for (unsigned int i=0; i< (index-1); i++)
	{
		pTmpEndNode = pTmpEndNode->pNext;
	}
	//赋值数据
	pTmpEndNode->pData = data;
	return true;
}
int main()
{
	OnlyList list;
	int a = 2;
	int b = 3;
	int c = 4;
	int d = 5;
	AddOnlyListBeginEle(&list,&a);
	AddOnlyListBeginEle(&list,&b);
	AddOnlyListBeginEle(&list,&c);
	AddOnlyListBeginEle(&list,&d);

	bool ret = false;
	int f = 100;
	ret = UpdateOnlyListEleByIndex(&list,10,&f);
	ret = UpdateOnlyListEleByIndex(&list,1,&f);
	//ret = DelOnlyListBeginEle(&list);
	//ret = DelOnlyListEndEle(&list);
	//ret = DelOnlyListEndEle(&list);
	//ret = DelOnlyListBeginEle(&list);
	//ret = DelOnlyListEle(&list,1);

	//ret = DelOnlyListBeginEle(&list);

	//ret = DelOnlyListBeginEle(&list);

	return 0;
}

 

 

C++封装

 

 

 

#ifndef _JXLIST_H_
#define _JXLIST_H_

#include <stdlib.h>

template<typename T>
class CJxList
{
protected:
	typedef struct _Node
	{
		T				pData;		//数据
		struct _Node*	pNext;		//前驱指针
		struct _Node*	pPre;		//后驱指针
	}Node;
public:
	CJxList(void):m_nSize(0),m_pHead(nullptr),m_pTail(nullptr)
	{
	}

	~CJxList()
	{

	}

	//在头增加数据
	bool AddBeginEle(T pdata)
	{
		//创建一个新的节点
		Node* pNewNode = (Node*)malloc(sizeof(Node));

		//复制数据指针变量
		pNewNode->pData = pdata;
		//把新节点元素的前驱指针为空
		pNewNode->pPre = nullptr;

		//把链表头指针赋给新节点的下一个节点的指针
		pNewNode->pNext = m_pHead;

		//把节点赋给头指针
		if (m_nSize == 0)
		{
			m_pTail = pNewNode;

		}
		else
		{
			m_pHead->pPre = pNewNode;
		}

		//把新节点的指针赋给链表的头指针
		m_pHead = pNewNode;
		//链表节点增加一个
		m_nSize++;

		return true;
	}

	//删除首数据并返回删除的数值
	T	DelBeginEle()
	{
		if (m_nSize == 0 /*|| m_pHead == nullptr*/)
		{
			return false;
		}
	
		//临时储存链表的头指针
		Node* pTmp = m_pHead;
		//把链表的头指针所指向的下一个节点指针复制链表的头指针
		m_pHead = pTmp->pNext;
		if (m_nSize == 1)
		{
			m_pTail = nullptr;
		}
		else
		{
			m_pHead->pPre = nullptr;
		}
		
		//有效个数减一
		m_nSize--;
	
		//释放空间
		//pTmp->pNext = nullptr;	//可有可无
		T ret = pTmp->pData;
		free(pTmp);
		return ret;
	}

	//删除链表中的尾元素
	T DelEndEle()
	{
		if (m_nSize == 0 /*|| m_pHead == nullptr*/)
		{
			return false;
		}
		//临时储存链表的头指针
		Node* pTmp = m_pTail;
		m_pTail = pTmp->pPre;

		//有效个数减一
		m_nSize--;

		//释放空间
		//pTmp->pNext = nullptr;
		T ret = pTmp->pData;
		free(pTmp);
		return ret;
	}

	//指定索引修改一个数据
	bool UpdataEleByIndex(unsigned int index,T data)		//index索引从1开始
	{
		if (index > (m_nSize) || m_nSize <= 0)
		{
			return false;
		}
		Node* pTmpEndNode = m_pHead;
		for (unsigned int i=0; i< (index-1); i++)
		{
			pTmpEndNode = pTmpEndNode->pNext;
		}
		//赋值数据
		pTmpEndNode->pData = data;
		return true;
	}

	//指定索引查找数据
	T FindEleByIndex(unsigned int index)		//index索引从1开始
	{
		if (index > (m_nSize) || index <= 0)
		{
			return (T)0;
		}
		Node* pTmpEndNode = m_pHead;
		for (unsigned int i=0; i< (index-1); i++)
		{
			pTmpEndNode = pTmpEndNode->pNext;
		}
		//赋值数据
		return pTmpEndNode->pData;
	} 

	/*将数据节点置为空表,释放原节点空间*/  
	void Clear()
	{
		Node* pTmpNext = m_pHead;	//临时节点指针
		Node* pDelNode = m_pHead;	//删除节点指针
		while (pTmpNext!=m_pTail)
		{
			//保存临时节点
			pDelNode = pTmpNext;
			//将临时节点的下一个节点指针保存
			pTmpNext = pTmpNext->pNext;
			//释放内存
			free(pDelNode);
			m_nSize--;
		}

		free(m_pTail);
		m_nSize--;

		m_pHead = nullptr;
		m_pTail = nullptr;
		//m_nSize = 0;
	}

	/*返回链表大小*/  
	int GetSize()
	{
		return m_nSize;
	}

	//判断是否为空
	bool IsEmpty(){ return (m_nSize ? false : true); }

private:
	unsigned int	m_nSize;	//元素个数
	Node*			m_pHead;	//头指针
	Node*			m_pTail;	//尾指针
};


#endif

 

 

 

 

 

 

 

 

 

 

posted @ 2016-12-13 22:47  jadeshu  阅读(210)  评论(0编辑  收藏  举报