学习笔记---数据结构之单链表

链表:由节点组成。节点由数据域和指针域。链表的内存不一定是连续的。

首先我们需要使用结构体定义一个链表的结点
struct Node//定义一个链表的节点
{
	//数据域
	int n;

	//指针域:存储下一个节点的地址
	Node *pnext;
};
创建一个n个节点的链表
Node* CreateList(int n)
{
	//定义一个指针表示链表的头指针,定义一个指针表示链表的尾指针
	Node *phead=nullptr,*prear=nullptr;

	for (int i=0;i<n;i++)
	{
		//创建一个新节点,并初始化
		Node *pnew=(Node*)malloc(sizeof(Node));
		cin>>pnew->n;
		pnew->pnext=nullptr;
		if(0==i)//链表为空
		{
			prear=phead=pnew;//新节点既是头节点也是尾节点
		}else
		{
			1.新节点作为新的头节点		头插法
			//pnew->pnext=phead;
			//phead=pnew;
			//2.新节点作为新的尾节点			尾插法
			prear->pnext=pnew;
			prear=pnew;
		}
	}

	return phead;
}

根据数组的创建链表//前闭后开
Node* CreateList(int *pBegin,int *pEnd)
{
	//定义一个指针表示链表的头指针,定义一个指针表示链表的尾指针
	Node *phead=nullptr,*prear=nullptr;

	for (int *p=pBegin;p!=pEnd;p++)
	{
		//创建一个新节点,并初始化
		Node *pnew=(Node*)malloc(sizeof(Node));
		pnew->n=*p;
		pnew->pnext=nullptr;
		if(p==pBegin)//链表为空
		{
			prear=phead=pnew;//新节点既是头节点也是尾节点
		}else
		{
			1.新节点作为新的头节点
			//pnew->pnext=phead;
			//phead=pnew;
			//2.新节点作为新的尾节点
			prear->pnext=pnew;
			prear=pnew;
		}
	}
	return phead;
}

遍历链表
void PrintList(const Node *phead)
{
		while(phead!=nullptr)//注意
		{
			cout<<phead->n<<endl;//输出节点的数据域
			phead=phead->pnext;//偏移到下一个节点
		}
}
插入一个节点
Node* InsterList(Node *phead,const Node *pnew,int pos)
{
	//创建一个新节点
	Node *p=new Node;
	p->n=pnew->n;
	p->pnext=nullptr;
	if(nullptr==phead)//判断链表是否为空
	{
		phead=p;
	}else
	{
		if(pos<=1)//表示插入的位置是第一个节点位置
		{
			//新节点作为新的头节点
			p->pnext=phead;
			phead=p;
		}else
		{
			//查找位置
			Node *pTemp=phead;//保存头节点的地址
			int i=1;
			while(pTemp->pnext!=nullptr)
			{
				++i;
				if(i>=pos)
					break;
				pTemp=pTemp->pnext;
			}
			//链接(先链接后面的节点,再链接前面节点)
			p->pnext=pTemp->pnext;
			pTemp->pnext=p;
		}
	}
	return phead;

删除节点(删除一个节点或者一个都不删除)
Node* DelList(Node *phead,int n)
{
	if(phead!=nullptr)
	{
		if(phead->n==n)//判断头节点是否满足需求
		{
			Node *ptemp=phead;
			phead=phead->pnext;
			free(ptemp);
			ptemp=nullptr;
		}else
		{
			Node *ptemp=phead;
			while(ptemp->pnext!=nullptr)
			{
				if(ptemp->pnext->n==n)
				{
					Node *p=ptemp->pnext;//保存删除节点的地址
					ptemp->pnext=p->pnext;
					free(p);
					p=nullptr;
					break;
				}
				ptemp=ptemp->pnext;
			}
		}
	}
	return phead;
}
删除所有满足条件的节点
Node* DelList(Node *phead, int n, bool isDelAll) {
	if (isDelAll) {
		if (phead->n == n)//判断头节点是否满足需求
		{
			//循环判断头结点的值是否是要删除的值
			while (phead->n == n)
			{
				Node *ptemp = phead;
				phead = phead->pnext;
				free(ptemp);
				ptemp = nullptr;
			}
		}
		else
		{
			Node *ptemp = phead;
			while (ptemp != nullptr && ptemp->pnext != nullptr)
			{
				if (ptemp->pnext->n == n)
				{
					Node *p = ptemp->pnext;//保存删除节点的地址
					ptemp->pnext = p->pnext;
					free(p);
					p = nullptr;
					continue;
				}
				ptemp = ptemp->pnext;
			}
		}
		return phead;
	}
	else {
		DelList(phead, n);
	}
}
对于已经排序的链表,删除相同节点(同一个值只保留一个)
Node* DelSameNodeList(Node *phead) {
	if (phead != nullptr) {
		Node* ptemp = phead;
		while (ptemp ->pnext != nullptr)
		{
			if (ptemp->n == ptemp->pnext->n)
			{
				Node *p = ptemp->pnext;
				if (p->pnext == nullptr)
				{
					ptemp->pnext = nullptr;
				}
				else {
					ptemp->pnext = p->pnext;
				}
				free(p);
				p = nullptr;
				continue;
			}
			ptemp = ptemp->pnext;
		}
	}
	return phead;
}
链表排序(这里使用每个节点里面的值来进行交换)
Node* OrderList(Node *phead) {
	if (phead != nullptr) {
		int n = 0, i;
		Node *p = phead;
		while (p!=nullptr)
		{
			n++;
			p = p->pnext;
		}
		for (p = phead,i = 1; i < n; i++, p = p->pnext)
			for (Node *q = p->pnext; q != nullptr; q = q->pnext)
				if (p->n < q->n)
				{
					int temp = p->n;
					p->n = q->n;
					q->n = temp;
				}
	}
	return phead;
}
清空链表
void ClearList(Node** pphead)//必须用址传递或者引用传递
{

		while(*pphead!=nullptr)
		{
			Node *ptemp=*pphead;//保存头节点的地址
			//头指针偏移到第二个节点
			*pphead=(*pphead)->pnext;
			//删除原来的头节点
				free(ptemp);
				ptemp=nullptr;
		}
}
主函数
int main()
{
	Node *phead=CreateList(5);
	//PrintList(phead);
	cout<<"******************"<<endl;

	//phead=DelList(phead,10, true);
	//phead = DelSameNodeList(phead);
	phead = OrderList(phead);
	PrintList(phead);

	//ClearList(&phead);//清空链表
	//PrintList(phead);//此时链表为空
	//插入节点
	//Node node={100,nullptr};
	//phead=InsterList(phead,&node,4);
	//phead=DelList(phead,10);
	//PrintList(phead);


	//cout<<"******************"<<endl;
	//int n[5]={43,455,65,54,43};
	//phead=CreateList(n,n+5);
	//PrintList(phead);


	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值