栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构:(c实现)单向链表,单链表的头增,尾增,头删,尾删,任意位置的删除与插入。

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构:(c实现)单向链表,单链表的头增,尾增,头删,尾删,任意位置的删除与插入。

目录: 一:什么是单链表      (1)单链表节点数据结构      (2)单链表结构物理图解 二:单链表的几种接口函数的实现       (1)单链表的尾插函数(顺序插入)         (2)单链表的尾删函数              (3)单链表的头增函数       (4)单链表的头删函数       (5)单链表查询函数       (6)单链表任意位置插入数据

       (7)单链表任意位置删除函数

一:什么是单链表 (1)单链表节点数据结构

 链表一般分成两块:一部分存储数据,另一部分存储下一个节点的地址。

(2)单链表结构物理图解

链表与顺序表不同,链表的存储形式不是一块物理地址连续的空间。而是在内存中随机存储。需要存入一个新的数据时,就malloc开辟一个新的节点。并将新开辟的空间的地址放置到上一个节点的指针中。 再将该节点的指针赋NULL。

而plist就是这个单链表的头,它存储的就是该链表的表头的地址。

二:单链表的几种接口函数的实现 (1)单链表的尾插函数(顺序插入)

1:因为是从该链表的尾部插入数据,所以先需要找到尾。(找尾)

尾部唯一的标识就是,该节点的指针域存储的数据为NULL(不指向任何空间)。那么我们可以通过这个条件,去遍历这个链表,找到尾。 

void SList_push_tail(SList* *ps, SListdata tmp)
{
	//如果该链表还是空的
	SList* cur = (*ps);
    SList* newnode = (SList*)malloc(sizeof(SList));
	newnode->datd = tmp;
	newnode->next = NULL;
	if ((*ps) == NULL)
	{
	
		(*ps) = newnode;
		return;
	}
	//说明已经有了一个或者多个节点
	//此时就需要找尾
	else
	{
		while (cur->next != NULL)
		{
			cur = cur->next;
		}//出这个循环时,说明cur->next中存储的是NULL
		//找到尾了
		cur->next = newnode;
	}
}
(2)单链表的尾删函数

将该链表的最后一个节点删除,那么同样的,我们也需要遍历该链表,找到尾。!!

但是在删除的同时,也需要将表尾的前一个节点的指针置NULL。但是对于单链表来说,如果我使用一个指针,遍历到了链表尾部,那就不能通过尾部的这个节点,找到上一个节点。

 所以我们使用两个指针去遍历这个顺序表,指针ptr向后遍历,发现这个节点不是表尾,就将这个节点地址交给cur,自己去下一个节点。当ptr->next==NULL时,直接释放该空间,并将cur->next置空。(当然还需要考虑只有一个节点,或者没有节点的情况。)

void SList_pop_tail(SList* *ps)
{
	SList* cur = *ps;
	SList* perv = *ps;
	if (*ps == NULL)
	{
		return;
	}
	else
	{
		if ((*ps)->next == NULL)
		{//只有一个节点
			free(*ps);
			*ps = NULL;
		}
		//找尾
		else
		{
           while (perv->next != NULL)
		   {
			  cur = perv;
			  perv = perv->next;
		   }
		      free(perv);
		      cur->next = NULL;
		}	
	}
}
(3)单链表的头增函数

单链表的头增,因为在定义时,我们始终有一个指针,指向该链表的表头(我称其为表头指针)。所以我们只需要将新生成的空间地址传给这个表头即可,并将刚才的表头指针指向的那个节点地址,交给现在的表头。

//头增
void SList_push_head(SList* * ps, SListdata tmp)
{
	SList* cur = *ps;
	SList* newnode = (SList*)malloc(sizeof(SList));
	newnode->datd = tmp;
	newnode->next = NULL;
	if (cur == NULL)
	{//没有节点
		(*ps) = newnode;
	}
	else
	{
		newnode->next = cur;
		(*ps) = newnode;
	}
}
 (4)单链表的头删函数

先将表头指针指向该链表的第一个节点,然后将第一个节点的空间直接释放掉。就可以完成操作。

//头删
void SList_pop_head(SList* * ps)
{
	SList* cur = *ps;
	if (cur == NULL)
	{//如果没有节点
		return;
	}
	//如果只有一个节点
	else if (cur->next == NULL)
	{
		free(cur);
		(*ps) = NULL;
	
	}
	else//有一个以上节点
	{
		(*ps) = cur->next;
		free(cur);
	}
}
(5)单链表查询函数

遍历查询单链表中的数据,查询到了,返回该数据的地址,否则返回空指针。

//查询函数,查询到这个数据的节点,返回该节点的地址
SList* SList_chage(SList* ps, SListdata tmp)
{
	if (ps == NULL)
	{
		return NULL;
	}
	else
	{
		while (ps->next != NULL)
		{//有多个节点
			if (ps->datd == tmp)
			{
				return ps;
			}
			ps = ps->next;
		}
		if (ps->datd == tmp)
		{//最后一个节点前面插入
			return ps;
		}
	}
	return NULL;
}
(6)单链表任意位置插入数据

根据上面的查询函数去实现,先找到哪个数据前面插入数据。找到了就插入,找不到默认尾插。(当然可以自己设置

//在数据3前面插入一个10   
SList*  pos=SList_chage(plist, 3);
	if (pos != NULL)
	{
		SList_push_any(&plist, pos, 10);
	}
	else
	{
		SList_push_tail(&plist, 10);
	}
//上面是主函数中的代码,找到了就在该数据前面插入,找不到默认尾插。


//下面是任意插入函数的代码

void SList_push_any(SList* * ps, SList* pos, SListdata tmp)
{
	SList* cur = *ps;
	SList* ptr = *ps;
	SList* newnode = (SList*)malloc(sizeof(SList));
	newnode->datd = tmp;
	newnode->next = NULL;
	if (cur == NULL)
	{
		printf("目的空间地址错误n");
		return;
	}
	else
	{
		if (cur == pos)
		{//头插
			SList_push_head(ps, tmp);
			return;
		}
		else
		{
			while (cur->next != NULL)
			{
				if (cur->next == pos)
				{
					newnode->next = pos;
					cur->next = newnode;
					return;
				}
				ptr = cur;
				cur = cur->next;
			}
		}
	}
}
(7)单链表任意位置删除函数

还是需要利用到之前的数据查询函数,当查询到了那个数据,就去删除那个节点,并将该节点前后两个节点链接起来。

//查询函数,写在主函数中测试的
	pos = SList_chage(plist, 18);
	if (pos != NULL)
	{
		SList_pop_any(&plist, pos);
	}


//删除任意位置
void SList_pop_any(SList** ps, SList* pos)
{
	SList* cur = *ps;
	SList* ptr = *ps;
	if (cur == NULL)
	{//空链表
		printf("目的空间地址错误n");
		return;
	}
	else
	{
		if (cur == pos)
		{   //头删
			SList_pop_head(ps);
		}
		else
		{
			while (cur->next != pos)
			{
				ptr = cur;
				cur = cur->next;
			}
			ptr = cur;
			cur = cur->next;
			ptr->next = cur->next;
			free(cur);
		}
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/879160.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号