首页 > 其他分享 >单链表的实现

单链表的实现

时间:2024-07-31 20:58:55浏览次数:8  
标签:pphead 单链 SLTNode 实现 pos next newnode NULL

1、开辟内存

/************开辟内存**************/
SLTNode* BuyListNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if(newnode == NULL)
	{
		printf("malloc failed\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

2、初始化链表

/************初始化链表**************/
void SListInit(SLTNode** pphead)
{
	*pphead = NULL;//传头指针的地址,通过解引用改变头指针。 
}

3、打印链表

/************打印链表**************/
void SListPrint(SLTNode* phead)
{
	SLTNode* cur = phead;//不能直接用phead(头指针)访问数据,改变phead的值会导致数据丢失。 
	while(cur != NULL)
	{
		printf("%d->",cur->data);
		cur = cur->next;
	} 
	
	printf("NULL\n");
}

4、尾插

/**************尾插 ***************/
void SListPushBack(SLTNode** pphead,SLTDataType x)
{
	assert(pphead); 
	//申请新节点 
	SLTNode* newnode = BuyListNode(x);
	
	//头指针为空不找尾 
	if(*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{	
		SLTNode* tail = *pphead;
		//找到尾,尾节点标志,next为空 
		while(tail->next != NULL)
		{
			tail = tail->next;
		}
		//串联节点 
		tail->next = newnode;
	}
}

5、尾删 

/***************尾删****************/
void SListPopBack(SLTNode** pphead)
{
	//空链表 
	if(*pphead == NULL)
	{
		return;
	} //assert(*pphead != NULL);
	
	
	//1个节点 
	if((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
		
	}
	//2个及以上节点 
	else
	{
		SLTNode* tail = *pphead;
	
		/* 
		两个方法均适用于大于一个的链表 
		方法一:借助一个变量
		SLTNode* prev = NULL;
		
		//while(tail->next),0(NULL)假,1真 
		while(tail->next != NULL)
		{
			prev = tail;//保存前一个指针 
			tail = tail->next;
		} 
		free(tail);
		prev->next = NULL; 
		*/
		
		//方法二:判断tail->next->next为空 
		while(tail->next->next != NULL)
		{ 
			tail = tail->next;
		} 
		free(tail->next);
		tail->next = NULL;	
	}
} 

6、头插


/**************头插 ***************/
void SListPushFront(SLTNode** pphead,SLTDataType x)
{
	SLTNode* newnode = BuyListNode(x);
	
	/*
	if(*pphead == NULL)
	{
		newnode->next = NULL;
		*pphead = newnode;	
	}
	else
	{
		newnode->next = *pphead;
		*pphead =newnode;	
	}
	*/
	
	newnode->next = *pphead;//对于空链表同样适用,因为空链表的头指针就是NULL。 
	*pphead =newnode;		
}

7、头删

/**************头删****************/
void SListPopFront(SLTNode** pphead)
{
	//空链表 
	if(*pphead == NULL)
	{
		return;
	}
	//assert(*pphead != NULL); 
	
	//1个及以上节点 
	else
	{
		SLTNode* next = (*pphead)->next;//先储存下一个节点的地址,否则free之后会丢失 
		free(*pphead);
		*pphead = next;
	}
}

8、查找

/**************查找数据***************/
SLTNode* SListFind(SLTNode* phead,SLTDataType x)
{
	SLTNode* cur = phead;
	while(cur)
	{
		if(cur->data == x)
		{
			return cur;//找到 
		}
		else
		{
			cur = cur->next;
		}
	}
	return NULL;//未找到 
} 

9、特定位置插入

/**************在pos位置之前(单链表不太适合)插入数据***************/
void SListInsertBefore(SLTNode** pphead,SLTNode* pos,SLTDataType x)
{
	SLTNode* newnode = BuyListNode(x);
	if(*pphead != pos)
	{
		SLTNode* pre = *pphead;//保存pos的前一个位置 
		
		/*
		找pos的前一个位置 
		SLTNode* cur = *pphead;
		while(cur->data != (*pos)->data)
		{
			pre = cur;
			cur =cur->next;
		}
		*/
		while(pre->next != pos)
		{
			pre = pre->next;
		}
	
		pre->next = newnode;
		newnode->next = pos;
	}
	else//头插 
	{
		newnode->next = pos; 
		*pphead = newnode;
			
	}	
}



/**************在pos位置之后插入数据 ***************/
void SListInsertAfter(SLTNode* pos,SLTDataType x) 
{
	assert(pos); 
	SLTNode* newnode = BuyListNode(x);
	newnode->next = pos->next;//注意先后顺序 
	pos->next = newnode;
}

10、特定位置删除

/**************在pos位置删除数据***************/
void SListErase(SLTNode** pphead,SLTNode* pos)
{
	assert(pphead);//地址不可能为空,错误的一种表示,方便调试 
	assert(pos); 
	if(*pphead == pos)
	{
		*pphead = pos->next;
		free(pos);
	}
	else
	{
		SLTNode* pre = *pphead;//保存pos的前一个位置
		while(pre->next != pos)
		{
			pre = pre->next;
		}
		pre->next = pos->next;
		free(pos);
	}
	
}



/**************删除pos位置之后数据***************/
void SListEraseAfter(SLTNode* pos)
{
	assert(pos->next != NULL);//断言 
	
	SLTNode* next = pos->next;
	pos->next = next->next;
	free(next); 
}

11、销毁链表

/**************毁灭链表***************/
void SListDestroy(SLTNode** pphead)
{
	assert(pphead);
	SLTNode* cur = *pphead;
	
	
	while(cur != NULL)
	{
		SLTNode* next = cur->next;//保存后一个地址 
		free(cur);
		cur = next;
	}
	
	*pphead = NULL;
 
}

标签:pphead,单链,SLTNode,实现,pos,next,newnode,NULL
From: https://blog.csdn.net/qq_63057731/article/details/140822568

相关文章

  • 细流汇海:在sklearn中实现增量特征聚类标签分配
    细流汇海:在sklearn中实现增量特征聚类标签分配在机器学习领域,聚类是一种无监督学习方法,用于将数据点分组成多个簇,使得同一簇内的数据点相似度高,而不同簇内的数据点相似度低。scikit-learn(简称sklearn)提供了多种聚类算法,但大多数算法都是批量处理的,对于动态数据或在线学习场......
  • 动态之美:Laravel动态路由参数的实现艺术
    动态之美:Laravel动态路由参数的实现艺术在Web开发中,路由是应用程序的神经系统,它负责将请求映射到相应的处理逻辑。Laravel框架提供了一种强大而灵活的路由系统,允许开发者定义动态路由参数,从而创建更具动态性和可扩展性的Web应用。本文将深入探讨Laravel的动态路由参数,解释......
  • 全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函
    全网最适合入门的面向对象编程教程:29类和对象的Python实现-断言与防御性编程和help函数的使用摘要:在Python中,断言是一种常用的调试工具,它允许程序员编写一条检查某个条件。本文主要介绍了断言的应用场景和特点以及assert语句的使用,同时介绍了防御性编程和help()函数......
  • 基于Java+SSM+jsp的医药管理系统的设计与实现(源码+数据库+讲解等)
    文章目录前言详细视频演示项目运行截图技术框架后端采用SSM框架前端框架JSP可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • 基于ASP.NET的医院病历管理系统设计与实现(源码+数据库+部署)
    文章目录前言详细视频演示项目运行截图技术框架后端采用.NET框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • iStore实现 SmartDNS + AdGuard Home IP优选+广告屏蔽
    iStore实现SmartDNS+AdGuardHomeIP优选+广告屏蔽参考自openwrt官方版安装配置AdGuardHome+smartdns告别广告烦扰教程软路由实测系列五SmartDNS和AdGuardHome都是用于优化DNS解析和提供广告拦截功能的工具,但它们各自有不同的特点和用途:SmartDNS主要功......
  • FPGA开发——按键控制LED的实现
    一、概述在上一篇文章中我们学习了按键的相关消抖及其使用,在这篇文章当中我们就针对通过按键实现LED的控制。1、按键原理图2、基本框架通过我们前面编写的按键消抖的文件和LED文件将按键和LED两个模块进行交互,从而达到按键控制LED的目的。 二、代码编写1、首先是按键......
  • Android开发 - (适配器)Adapter类中CursorAdapter实现类详细解析
    作用将Cursor对象中的数据与AdapterView组件(如ListView、GridView等)进行绑定。以下是CursorAdapter的主要作用:1.数据源绑定数据源连接:CursorAdapter通过Cursor对象作为数据源,实现了从数据库或其他数据源(如ContentResolver查询结果)中读取数据的功能。这使得开发者能够轻松地......
  • 自定义线程池实现(一)
    预期目标1.实现一个相对完备的线程池2.自定义拒绝策略(下一节)线程池的基本参数1.核心线程数2.超时时间3.拒绝策略(在下一篇中添加)4.工作队列5.任务队列工作机制当添加一个任务到线程池中时,线程池会判断工作线程数量是否小于核心线程数,若小于创建工作线程,执行任务;反......
  • js中两种设置子类原型(prototype)来实现原型式继承的本质区别
    在JavaScript中,这两种设置子类(Child)原型(prototype)的方法虽然都能实现继承的基本功能,但它们之间存在一些重要的区别和潜在的陷阱。1. Child.prototype=Object.create(Parent.prototype);这个方法使用Object.create()来创建一个新对象,其原型(__proto__)被设置为Parent.prototy......