嵌入式学习第三十天!(单向链表练习)

1. 单向链表的逆序:

cpp 复制代码
int Is_Empty_Link(LINK_LIST *plist)
{
	return plist->phead == NULL;
}

void Reverse_Link(LINK_LIST *plist)
{
	LINK_NODE *ptmp = plist->phead;
	LINK_NODE *pinsert = NULL;

	plist->phead = NULL;
	if(Is_Empty_Link(plist))
	{
		return;
	}
	else
	{
		while(ptmp != NULL)
		{
			pinsert = ptmp;
			ptmp = ptmp->pnext;

			pinsert->pnext = plist->phead;
			plist->phead = pinsert;
		}
	}

	return;
}

在这里的逆序,利用了头插法的思想,因为利用头插法插入数据,数据是逆序插入的,最后插入的数据在最前面,最先插入的数据在最后面,那么逆序也可以使用这个思想。

2. 找到单向链表中的中间结点

cpp 复制代码
LINK_NODE *Find_Center_Link(LINK_LIST *plist)
{
	LINK_NODE *pfast = plist->phead;
	LINK_NODE *pslow = plist->phead;

	while(pfast != NULL)
	{
		pfast = pfast->pnext;
		if(pfast == NULL)
		{
			break;
		}
		pfast = pfast->pnext;
		pslow = pslow->pnext;
	}

	return pslow;
}

采用链表中比较常用的快慢指针法,那么快指针每次走两步,慢指针每次走一步,当快指针走到等于NULL的时候,慢指针刚好走到了中间结点,但是在这个地方,如果遇到偶数个结点的单向链表,那么得到的中间结点为中间的后一个结点。如果想要中间结点的前一个结点的话,那么需要修改一下判断条件:

cpp 复制代码
LINK_NODE *Find_Center_Link(LINK_LIST *plist)
{
	LINK_NODE *pfast = plist->phead;
	LINK_NODE *pslow = plist->phead;

	while(1)
	{
		pfast = pfast->pnext;
		if(pfast == NULL)
		{
			break;
		}
		pfast = pfast->pnext;
		if(pfast == NULL)
		{
			break;
		}
		pslow = pslow->pnext;
	}
	
	return pslow;
}

3. 找到单向链表的倒数第K个结点

cpp 复制代码
LINK_NODE *Find_Last_K_Node(LINK_LIST *plist, int K)
{
	LINK_NODE *pfast = plist->phead;
	LINK_NODE *pslow = plist->phead;

	for(int i = 0; i < K; i++)
	{
		if(pfast == NULL)
		{
			return NULL;
		}
		pfast = pfast->pnext;
	}

	while(pfast != NULL)
	{
		pfast = pfast->pnext;
		pslow = pslow->pnext;
	}

	return pslow;
}

同样可以使用快慢指针法的思想,让快指针先走K步,然后再让快指针和慢指针同时一起走,当快指针走到等于NULL的时候,那么慢指针刚好比慢指针少K步,也就是倒数第K个结点

4. 删除单向链表的某个结点

cpp 复制代码
int Delete_Link_Node(LINK_LIST *plist, DATA_TYPE data)
{
	if(Is_Empty_Link(plist))
	{
		return 0;
	}
	
	LINK_NODE *pfree = plist->phead;
	LINK_NODE *ppre = NULL;
	int del_cnt = 0;
		
	while(pfree != NULL)
	{
		if(pfree->data == data)
		{
			if(pfree == plist->phead)
			{
				plist->phead = pfree->pnext;
				free(pfree);
				pfree = plist->phead;
			}
			else
			{
				ppre->pnext = pfree->pnext;
				free(pfree);
				pfree = ppre->pnext;
			}
			plist->curlen--;
			del_cnt++;
		}
		else
		{
			ppre = pfree;
			pfree = pfree->pnext;
		}
	}

	return del_cnt;
}

可以发现这段代码可以将所有数据为data的链表结点都删除了,如果只想删除第一个的话,那就在找到第一个数据为data的结点以后,将结点free掉,然后直接return,那么程序就实现了只删除第一个。

5. 实现单向链表的升序排序(插入排序的思想)

cpp 复制代码
int Insert_Sort_Link(LINK_LIST *plist)
{
	LINK_NODE *pinsert = NULL;
	LINK_NODE *ptmp = plist->phead;

	plist->phead->pnext = NULL;

	while(ptmp != NULL)
	{
		pinsert = ptmp;
		ptmp = ptmp->pnext;

		if(pinsert->data <= plist->phead->data)
		{
			pinsert->pnext = plist->phead;
			plist->phead = pinsert;
		}
		else
		{	
			LINK_NODE *perg = plist->phead;
			while(perg->pnext != NULL && pinsert->data >= perg->pnext->data)
			{
				perg = perg->pnext;
			}
			pinsert->pnext = perg->pnext;
			perg->pnext = pinsert;
		}
	}

	return 0;
}
相关推荐
Hello_Embed7 小时前
STM32HAL 快速入门(十九):UART 编程(二)—— 中断方式实现收发及局限分析
笔记·stm32·单片机·嵌入式硬件·学习
天上的光8 小时前
关于学习的一些感悟
学习
Ripple123128 小时前
数据结构:顺序表与链表
数据结构·链表
red_redemption8 小时前
自由学习记录(95)
学习
东风西巷9 小时前
Balabolka:免费高效的文字转语音软件
前端·人工智能·学习·语音识别·软件需求
XISHI_TIANLAN11 小时前
【多模态学习】Q&A3:FFN的作用?Embedding生成方法的BERT和Word2Vec?非线性引入的作用?
学习·bert·embedding
KFCcrazy412 小时前
嵌入式学习日记(39)51单片机
嵌入式硬件·学习·51单片机
MuMuMu#12 小时前
JAVA NIO学习笔记基础强化学习总结
java·学习·nio
lingggggaaaa12 小时前
小迪安全v2023学习笔记(七十九讲)—— 中间件安全&IIS&Apache&Tomcat&Nginx&CVE
笔记·学习·安全·web安全·网络安全·中间件·apache
我登哥MVP12 小时前
Java File 类学习笔记
java·笔记·学习