【数据结构基础_有[*pHead]和[*pEnd]的单向链表_(C++实现)】

此文为上一篇文章改为C++格式实现(多文件形式)

头文件

#pragma once
#include<iostream>
using namespace std;

struct Node
{
	int iData;
	Node* pNext;
};

class List
{
private:
	Node* pHead;
	Node* pEnd;	//pEnd指针是为了增加尾添加的效率,否则就要循环找尾
	int iCount = 0;
public:
	List();
	~List();
private:
	void FreeList();
	void FreeListNULL();
public:
	void AddToEnd(int iData);
	void AddToEndNopEnd(int iData);
	void Look();
	void AddToHead(int iData);
	Node* FindNodeByIndex(int iIndex);
	Node* FindNodeByData(int iData);
	void InsertNodeByIndex(int iIndex, int iData);
	void AddSomeNode(unsigned int iCount, unsigned int iData);
	void ChengeData(int iResData, int iDecData);
	void ChengeSomeData(int iResData, int iDecData);
	void ChengeSomeDataText(int iResData, int iDecData);
	void DeleteHead();
	void DeleteEnd();
	Node* DeleteOneDataByData(int iData);
	void DeleteAllDataByData(int iData);
	void DeleteDataByIndex(int iIndex);
	void SwapByData(int iData1, int iData2);
	void SwapByIndex(int iIndex1, int iIndex2);
	void SwapByChangePoint(int iIndex1, int iIndex2);
	void ReverseByData();
	void ReverseByPoint();
	int GetListNodeCount();
};


函数实现

#include"dl.h"

List::List()
{
	pHead = NULL;
	pEnd = NULL;
	iCount = 0;
}
List::~List()
{
	FreeListNULL();
}

void List::ReverseByPoint()
{
	Node* pHead = this->pHead;
	//参数合法性检测
	if (NULL == pHead || NULL == pHead->pNext)
	{
		return;
	}
	int iCount = GetListNodeCount();
	int i = 0, j = iCount - 1;
	for (; i < j; i++, j--)
	{
		SwapByChangePoint(i, j);
	}
}
void List::ReverseByData()
{
	//参数合法性检测
	if (NULL == pHead || NULL == pHead->pNext)
	{
		return;
	}
	int iCount = GetListNodeCount();
	int i = 0, j = iCount - 1;
	for (; i < j; i++, j--)
	{
		SwapByIndex(i, j);
	}
}
int List::GetListNodeCount()
{
	Node* pHead = this->pHead;
	int iCount = 0;
	while (NULL != pHead)
	{
		iCount++;
		pHead = pHead->pNext;
	}
	return iCount;
}
void List::SwapByChangePoint(int iIndex1, int iIndex2)
{
	Node* pHead = this->pHead;
	//参数合法性检测
	if (NULL == pHead || NULL == pHead->pNext || iIndex1 == iIndex2 || iIndex1 < 0 || iIndex2 < 0)
	{
		return;
	}
	//确定大小关系
	int iMin = iIndex1;
	int iMax = iIndex2;
	if (iIndex1 > iIndex2)
	{
		iMin = iIndex2;
		iMax = iIndex1;
	}
	//根据下标找节点
	Node* pMin = FindNodeByIndex(iMin);
	Node* pMax = FindNodeByIndex(iMax);
	//找不到就结束
	if (NULL == pMin || NULL == pMax)
	{
		cout<<"查无此节点\n";
		return;
	}
	//头尾交换
	if (pMin == pHead && pMax == pEnd)
	{
		if (pHead->pNext == pEnd)  //两个节点
		{
			pEnd->pNext = pHead;
			pHead->pNext = NULL;
			//交换指向
			pHead = pEnd;
			pEnd = pHead->pNext;
		}
		else //多个节点
		{
			//找到尾巴的前一个节点
			Node* pMaxPre = FindNodeByIndex(iMax - 1);
			//尾巴变头
			pEnd->pNext = pHead->pNext;
			//头变尾巴
			pMaxPre->pNext = pHead;
			//头下一个为NULL
			pHead->pNext = NULL;
			//交换指向
			pHead = pEnd;
			pEnd = pMaxPre->pNext;
		}
	}
	//头和中间交换
	else if (pMin == pHead && pMax != pEnd)
	{
		//相邻
		if (pMin->pNext == pMax)
		{
			pMin->pNext = pMax->pNext;
			pMax->pNext = pMin;
			pHead = pMax;
		}
		//不相邻
		else
		{
			//找pMax的前一个指针
			Node* pMaxPre = FindNodeByIndex(iMax - 1);
			//记录头的下一个节点 即链表第二个节点
			Node* pHeadNext = pMin->pNext;
			//头节点连在max的位置上
			pMin->pNext = pMax->pNext;
			pMaxPre->pNext = pMin;
			//pMax挪到头
			pMax->pNext = pHeadNext;
			//改变新的头
			pHead = pMax;
		}
	}
	//尾和中间交换
	else if (pMin != pHead && pMax == pEnd)
	{
		if (pMin->pNext == pMax)  //相邻
		{
			//找到pMin的前一个
			Node* pMinPre = FindNodeByIndex(iMin - 1);
			//先把尾巴放中间
			pMinPre->pNext = pMax;
			pMax->pNext = pMin;
			//pMin next = NULL
			pMin->pNext = NULL;
			pEnd = pMin;
		}
		//不相邻
		else
		{
			//找到pMin的前一个
			Node* pMinPre = FindNodeByIndex(iMin - 1);
			//找pMax的前一个指针
			Node* pMaxPre = FindNodeByIndex(iMax - 1);
			//pmax放中间去
			pMinPre->pNext = pMax;
			pMax->pNext = pMin->pNext;
			//pMin放尾巴上去
			pMaxPre->pNext = pMin;
			pMin->pNext = NULL;
			pEnd = pMin;
		}
	}
	//中间两个相互交换
	else if (pMin != pHead && pMax != pEnd)
	{
		//相邻
		if (pMin->pNext == pMax)
		{
			//找到pMin的前一个节点
			Node* pMinPre = FindNodeByIndex(iMin - 1);
			Node* pMaxNext = pMax->pNext;
			//将pMax装在pMin 与pMinPre中间
			pMinPre->pNext = pMax;
			pMax->pNext = pMin;
			//把pMax拿下来
			pMin->pNext = pMaxNext;
		}
		//不相邻
		else
		{
			//找到pMin的前一个
			Node* pMinPre = FindNodeByIndex(iMin - 1);
			Node* pMinNext = pMin->pNext;
			//找pMax的前一个指针
			Node* pMaxPre = FindNodeByIndex(iMax - 1);
			Node* pMaxNext = pMax->pNext;
			//将pMin撞到pMax的位置
			pMaxPre->pNext = pMin;
			pMin->pNext = pMaxNext;
			//将pMax撞到pMin的位置
			pMinPre->pNext = pMax;
			pMax->pNext = pMinNext;
		}
	}
}
void List::SwapByIndex(int iIndex1, int iIndex2)
{
	if (NULL == pHead)
		return;
	//查找
	Node* pT1 = FindNodeByIndex(iIndex1);
	Node* pT2 = FindNodeByIndex(iIndex2);
	//都找到才能交换
	if (pT1 != NULL && pT2 != NULL)
	{
		//交换成员
		//int temp = pT1->iData;
		//pT1->iData = pT2->iData;
		//pT2->iData = temp;
		Node p = *pT1;
		memcpy(pT1, pT2, 4);
		memcpy(pT2, &p, 4);
	}
}
void List::SwapByData(int iData1, int iData2)
{
	if (NULL == pHead)
		return;
	//查找
	Node* pT1 = FindNodeByData(iData1);
	Node* pT2 = FindNodeByData(iData2);
	//都找到才能交换
	if (pT1 != NULL && pT2 != NULL)
	{
		//交换成员
		//Node p = *pT1;
		//*pT1 = *pT2;
		//*pT2 = p;
		//int temp = pT1->iData;
		//pT1->iData = pT2->iData;
		//pT2->iData = temp;
		Node p = *pT1;
		memcpy(pT1, pT2, 4);
		memcpy(pT2, &p, 4);
	}
}
void List::DeleteDataByIndex(int iIndex)
{
	Node* pHead = this->pHead;
	if (NULL == pHead)
		return;
	if (0 == iIndex)
		DeleteHead();
	else
	{
		//找前一个节点
		Node* pTemp = FindNodeByIndex(iIndex - 1);
		if (pTemp != NULL)
		{
			if (pTemp->pNext == pEnd)
				DeleteEnd();
			//记录被删除的节点
			Node* pT = pTemp->pNext;
			//链接
			pTemp->pNext = pT->pNext;
			//释放
			delete pT;
		}
		else
		{
			cout << "查无此节点\n";
		}
	}
}
void List::DeleteAllDataByData(int iData)
{
	Node* pHead = this->pHead;
	if (NULL == pHead)
		return;
	Node* pTemp = DeleteOneDataByData(iData);
	while (pTemp != NULL)
	{
		pTemp = DeleteOneDataByData(iData);
	}
}
Node* List::DeleteOneDataByData(int iData)
{
	Node* pHead = this->pHead;
	if (NULL == pHead)
		return NULL;
	if (pHead->iData == iData)
	{
		DeleteHead();
		return pHead;
	}
	else if (pEnd->iData == iData)
	{
		DeleteEnd();
		return pHead;
	}
	else
	{
		//循环找节点
		Node* pTemp = pHead;
		while (pTemp->pNext != NULL)
		{
			if (pTemp->pNext->iData == iData)
				break;
			pTemp = pTemp->pNext;
		}
		//判断
		if (pTemp->pNext != NULL)
		{
			Node* pT = pTemp->pNext; //记录
			pTemp->pNext = pT->pNext;
			delete  pT;
			return pHead;   //return pTemp->pNext  ----- pHead
		}
		else
		{
			cout << "查无此节点\n";
			return NULL;
		}
	}
}
void List::DeleteEnd()
{
	Node* pHead = this->pHead;
	//参数合法性检测
	if (NULL == pHead)
		return;
	if (pHead == pEnd || pHead->pNext == NULL)//只有一个节点
	{
		delete pHead;
		pHead = NULL;
		pEnd = NULL;
	}
	else
	{
		//找到结尾的前一个
		Node* pT = pHead;
		while (pT->pNext != pEnd)
		{
			pT = pT->pNext;
		}
		delete pEnd;
		pEnd = pT;
		pEnd->pNext = NULL;
	}
}
void List::DeleteHead()
{
	Node* pHead = this->pHead;
	//参数合法性检测
	if (NULL == pHead)
		return;
	if (pHead == pEnd || pHead->pNext == NULL)//只有一个节点
	{
		delete pHead;
		pHead = NULL;
		pEnd = NULL;
	}
	else
	{
		Node* pT = pHead;
		pHead = pHead->pNext;
		delete pT;
	}
}
void List::ChengeSomeData(int iResData, int iDecData)
{
	Node* pHead = this->pHead;
	//参数合法性检测
	if (NULL == pHead)
	{
		cout << "查无此节点\n";
		return;
	}
	while (pHead != NULL)
	{
		if (pHead->iData == iResData)
			pHead->iData = iDecData;
		pHead = pHead->pNext;
	}
}
void List::ChengeSomeDataText(int iResData, int iDecData)
{
	//参数合法性检测
	if (NULL == pHead)
	{
		cout << "查无此节点\n";
		return;
	}
	while (FindNodeByData(iResData) != NULL)
	{
		ChengeData(iResData, iDecData);
	}
}
void List::ChengeData(int iResData, int iDecData)
{
	Node* pRec = FindNodeByData(iResData);
	if (NULL == pRec)
	{
		cout << "查无此节点\n";
	}
	else
	{
		pRec->iData = iDecData;
	}
}
void List::AddSomeNode(unsigned int iCount, unsigned int iData)
{
	for (unsigned int i = 0; i < iCount; i++)
	{
		AddToEnd(iData);
	}
}
void List::InsertNodeByIndex(int iIndex, int iData)
{
	//参数合法性检测
	if (iIndex < 0)
	{
		cout << "下标输入有误,请重新输入\n";
		return;
	}
	//下标为0,直接头添加
	if (0 == iIndex)
	{
		AddToHead(iData);
	}
	else
	{
		//找位置
		Node* pTemp = FindNodeByIndex(iIndex - 1);
		if (pTemp != NULL)
		{
			//申请节点空间
			Node* pT = new(Node);
			if (pT != NULL)
			{
				//节点成员赋值
				pT->iData = iData;
				pT->pNext = NULL;
				//链接 先连后断
				pT->pNext = pTemp->pNext;
				pTemp->pNext = pT;
			}
		}
		else
		{
			cout << "查无此节点";
		}
	}
}
Node* List::FindNodeByData(int iData)
{
	Node* pHead = this->pHead;
	//参数合法性检测
	if (NULL == pHead || iData < 0)
	{
		cout << "链表为空/位置输入有误,无法查节点\n";
		return NULL;
	}
	//循环链表
	while (pHead != NULL)
	{
		if (pHead->iData == iData)
			return pHead;
		pHead = pHead->pNext;
	}
	return NULL;
}
Node* List::FindNodeByIndex(int iIndex)
{
	Node* pHead = this->pHead;
	//参数合法性检测
	if (NULL == pHead || iIndex < 0)
	{
		cout << "链表为空/位置输入有误,无法查节点\n";
		return NULL;
	}
	//循环链表
	int i = 0;
	while (pHead != NULL)
	{
		if (i == iIndex)
			return pHead;
		i++;
		pHead = pHead->pNext;
	}
	cout << "位置输入过大,无法查节点\n";
	return NULL;
}
void List::AddToHead(int iData)
{
	//创建节点
	Node* pTemp = new(Node);
	if (NULL != pTemp)
	{
		//节点成员赋值
		pTemp->iData = iData;
		pTemp->pNext = NULL;
		//连接链表
		if (NULL == pHead)//空链表
		{
			//*pHead = pTemp;
			pEnd = pTemp;
		}
		else
		{
			pTemp->pNext = pHead;
			//*pHead = pTemp;
		}
		pHead = pTemp;
	}
}
void List::Look()
{
	Node* pHead = this->pHead;
	while (pHead != NULL)
	{
		cout << " " << (pHead->iData);
		pHead = pHead->pNext;
	}
	cout << endl;
}
void List::FreeList()
{
	Node* pTemp = pHead;
	while (pTemp != NULL)
	{
		Node* pt = pTemp;
		pTemp = pTemp->pNext;
		delete pt;
	}
	pHead = NULL;
	pEnd = NULL;
}
void List::FreeListNULL()
{
	Node* pTemp = pHead;
	while (pTemp != NULL)
	{
		Node* pt = pTemp;
		pTemp = pTemp->pNext;
		delete pt;
	}
	pHead = NULL;
	pEnd = NULL;
}
void List::AddToEndNopEnd(int iData)
{
	//创建节点
	Node* pTemp = new(Node);
	if (NULL != pTemp)
	{
		//节点成员赋值
		pTemp->iData = iData;
		pTemp->pNext = NULL;
		//链接
		if (NULL == pHead)
		{
			pHead = pTemp;
		}
		else
		{
			Node* pt = pHead;
			while (pt->pNext != NULL)		//找尾巴
			{
				pt = pt->pNext;
			}
			pt->pNext = pTemp;
		}
	}
}
void List::AddToEnd(int iData)
{
	//创建节点
	Node* pTemp = new(Node);
	if (NULL != pTemp)
	{
		//节点成员赋值
		pTemp->iData = iData;
		pTemp->pNext = NULL;
		//连接链表
		if (NULL == pHead)//空链表
		{
			pHead = pTemp;
			//*pEnd = pTemp;
		}
		else
		{
			pEnd->pNext = pTemp;
			//*pEnd = pTemp;
		}
		pEnd = pTemp;
	}

}

主函数

#include<iostream>
#include"dl.h"
using namespace std;



int main()
{
	List ls;

	ls.AddToEnd(1);
	ls.AddToEnd(2);
	ls.AddToEndNopEnd(5);
	ls.AddToHead(3);
	//ls.FindNodeByIndex(2);
	//ls.FindNodeByData(2);
	ls.InsertNodeByIndex(2,3);


	ls.Look();
	
	

	return 0;
}

perfect~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千北@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值