数据结构--单向链表(c++)

1、单向链表:必要属性    头指针指针, 元素的实际长度, 结构体:数据、指向下一节点的指针

2、操作方法:

	//判断链表是否为空
	//清空链表
	//返回链表的长度
	//获取索引处元素内容
	//获取指定内容的第一个元素的位置
	//插入一个节点
	//删除一个节点



#include  <stdlib.h>
#include <windows.h>
#include <iostream>

template<class Type>
class CLinkList
{

public:
	typedef  struct _NODE
	{
		Type nData;
		_NODE * pNext;
	}NODE, *PNODE;

public:
	CLinkList():m_nHead(nullptr),m_nLen(0)
	{

	}
	~CLinkList()
	{

	}

public:


	//判断链表是否为空
	bool LListIsEmpty()
	{
 
		return (m_nLen == 0|| m_nHead==nullptr ) ? true : false;
	}

	//清空链表
	void LListCls()
	{
		//如果头指针不为空  或者 长度不为0 则进行清空链表
		if (m_nHead != nullptr || m_nLen != 0)
		{
			//记录当前指针变量
			PNODE temp = m_nHead;
			while(temp->pNext)
			{
				//将头指针后移
				m_nHead = temp->pNext;
				delete temp;
				temp = nullptr;
				//将新的头指针赋给临时变量
				temp = m_nHead;
			}

			//删除最后一个节点  并将长度设置为0
			delete m_nHead;
			m_nHead = nullptr;
			m_nLen = 0;
		}
	}

	//返回链表的长度
	int LListLen()
	{
		return m_nLen;
	}

	//获取索引处元素内容
	bool LListGetEle(_In_ int idx, _Out_ Type &type)
	{
		//判断参数
		if (idx<0 || idx>m_nLen)
		{
			return false;
		}

		//判断是否为空
		if (m_nHead == nullptr || m_nLen == 0)
		{
			return false;
		}

		//遍历到要寻找的位置  从0开始 到idx前一个节点 就可以获取到idx中的内容
		PNODE temp = m_nHead;
		for (int i=0; i<idx; i++)
		{
			temp = temp->pNext;
		}

		//将内容传出
		memcpy_s(&type, sizeof(Type), &(temp->nData), sizeof(Type));
		return true;
	}

	//获取指定内容的第一个元素的位置
	int LListGetIdx(_In_ Type data)
	{
		//判断是否为空
		if (LListIsEmpty())
		{
			return -1;
		}

		//遍历 获取所在的位置
		PNODE temp = m_nHead;
		for (int i=0; i<m_nLen; i++)
		{
			//比较内容
			if (!memcmp(&data,  &temp->nData, sizeof(Type)))
			{
				return i;
			}
			temp = temp->pNext;
		}
		return -1;
	}

	//插入一个节点
	bool LListInsert(_In_ int idx, _In_ Type data)
	{
		// 判断参数
		if (idx < 0 || idx > m_nLen)
		{
			return false;
		}

		//判断头结点是否为空
		if (!m_nHead)
		{
			m_nHead = new NODE;
			m_nHead->nData = data;
			m_nHead->pNext = nullptr;
			m_nLen++;
			return true;
		}

		//找到要插入的节点
		PNODE temp = new NODE;
		temp->nData = data;
		temp->pNext = nullptr;

		//判断是否在头节点处插入
		if (idx == 0)
		{
			//将该节点的pNext 指向 当前的头指针
			temp->pNext = m_nHead;

			//将头指针指向头节点
			m_nHead = temp;

			//长度自增
			m_nLen++;
			return true;
		}

		//插入的是非头结点
		//记录头指针
		PNODE pre = m_nHead;
		//将记录指针移动到添加位置的前面
		for(int i=0; i<idx; i++)
		{
			pre = pre->pNext;
		}

		//将当前节点的pNext赋值给temp的pNext
		temp->pNext = pre->pNext;

		//将temp的地址赋给 当前节点的pNext
		pre->pNext = temp;

		//长度自增
		m_nLen++;

		return true;
	}

	//删除一个节点
	bool LListDel(_In_ int idx, _Out_ Type& data)
	{
		//判断参数
		if (idx<0 || idx>=m_nLen)
		{
			return false;
		}

		//判断是否为空
		if (LListIsEmpty())
		{
			return false;
		}

		//找到要删除的位置
		//如果是头节点
		if (idx == 0)
		{
			//将要删除的数据 赋值给传出数据
			data = m_nHead->nData;

			//创建一个临时节点
			PNODE temp = new NODE;
			temp = m_nHead;
			temp = temp->pNext;
			m_nHead = temp;

			delete temp;
			temp = nullptr;
			//长度自减
			m_nLen--;
			return true;
		}

		//正常情况
		//记录当前指针
		PNODE temp = m_nHead;
		
		//遍历到 要删除节点的前一个节点
		for (int i = 0; i < idx-1; i++)
		{
			//当前节点的指针 移动到下一个节点
			temp = temp->pNext;
		}
		
		//删除

		//记录当前节点的pNext 此时temp为要删除的节点前一个节点
		PNODE pre = nullptr;
		pre = temp->pNext;  //要删除节点的地址
		//将数据传出  
		data = pre->nData;
		temp->pNext = pre->pNext;
		delete pre;
		pre = nullptr;

		m_nLen--;
		return true;
	}

	//打印输出
	void pri()
	{
		PNODE temp = m_nHead;
		for (int i=0 ; i<m_nLen; i++)
		{
			std::cout << temp->nData <<std::endl;
			temp = temp->pNext;
		}
		std::cout<<std::endl;
	}
private:
	PNODE m_nHead;		//头指针
	int m_nLen;			//元素个数
};


int main()
{
	
	CLinkList<int>  cll;
	cll.LListInsert(0, 11);
	cll.LListInsert(0, 22);
	cll.LListInsert(0, 33);

	cll.pri();

 
	system("pause");
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值