【数据结构】链表操作C实现

#####数据类型的定义

typedef int DataType; 

typedef struct ListNode
{ 
	DataType data; 
	struct ListNode *next; 
} ListNode;

#####链表的初始化和销毁
链表的初始化----->构造一条空链表
链表的销毁----->销毁每个结点

//初始化
void ListInit(ListNode **pFirst)
{
	*pFirst = NULL; 
}
//销毁
void ListDestory(ListNode **pFirst)
{
	ListNode *cur = NULL;
	ListNode *del = NULL;
	assert(*pFirst);
	cur = *pFirst;
	while(cur->next != NULL)
	{
		del = cur;
		cur = cur->next;
		free(del);
	}
	free(cur);
}

#####打印链表

void ListPrint(ListNode **pFirst)
{
	ListNode *cur = NULL;
	assert(*pFirst != NULL);
	cur = *pFirst;
	while(cur != NULL)
	{
		printf("%d ",cur->data);
		cur = cur->next;
	}
	printf("\n");
}

#####查找
按值查找,如果找到了返回第一个找到的结点指针,如果没找到,返回NULL。代码如下:

ListNode *ListFind(ListNode **pFirst, DataType data)
{
	ListNode *cur = NULL;
	assert(*pFirst != NULL);
	cur = *pFirst;
	while(cur != NULL)
	{
		if(cur->data == data)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

#####增加数据
在增加数据前,需要一个函数来创建一个新结点,函数返回新结点的地址,通过改变链表中结点的next指向来将新结点加入到链表中。代码如下:

ListNode *CreateNode(DataType data)
{
	ListNode *NewNode = (ListNode *)malloc(sizeof(DataType));
	NewNode->data = data;
	NewNode->next = NULL;
	return NewNode;
}

######尾插
这里写图片描述
代码如下:

void ListPushBack(ListNode **pFirst, DataType data)
{
	ListNode *cur = NULL;
	//如果链表为空
	if(*pFirst == NULL)
	{
		*pFirst = CreateNode(data);
		return ;
	}
	//链表不为空
	cur = *pFirst;
	while(cur->next != NULL)
	{
		cur = cur->next;
	}
	cur->next = CreateNode(data);
}

######头插
这里写图片描述
代码如下:

void ListPushFront(ListNode **pFirst, DataType data)
{
	ListNode *cur = NULL;
	//如果链表为空
	if(*pFirst == NULL)
	{
		*pFirst = CreateNode(data);
		return ;
	}
	//链表不为空
	cur = *pFirst;
	*pFirst = CreateNode(data);
	(*pFirst)->next = cur;
}

#####指定位置插入(插入到结点前)

这里写图片描述
代码如下:

void ListInsert(ListNode **pFirst, ListNode *pos, DataType data)
{
	ListNode *cur = NULL;
	ListNode *NewNode = NULL;
	assert(*pFirst != NULL);
	if(pos == NULL)
		return ;
	//如果在第一个元素位置前插入,调用头插函数
	if(pos == *pFirst)
	{
		ListPushFront(pFirst, data);
	}
	cur = *pFirst;
	NewNode = CreateNode(data);
	while(cur->next != pos)
	{
		cur = cur->next;
	}
	cur->next = NewNode;
	NewNode->next = pos;
}

#####删除数据
######尾删
这里写图片描述
代码如下:

void ListPopBack(ListNode **pFirst)
{
	ListNode *cur = NULL;
	ListNode *del = NULL;
	assert(*pFirst != NULL);
	//如果链表只有一个元素
	if((*pFirst)->next == NULL)
		*pFirst = NULL;
	//如果链表有多个元素
	cur = *pFirst;
	while(cur->next->next != NULL)
	{
		cur = cur->next;
	}
	del = cur->next->next;
	cur->next = NULL;
	free(del);
}

######头删
这里写图片描述
代码如下:

void ListPopFront(ListNode **pFirst)
{
	ListNode *del = NULL;
	assert(*pFirst != NULL);
	//如果链表只有一个元素
	if((*pFirst)->next == NULL)
	{
		*pFirst = NULL;
	}
	//如果链表有多个元素
	del = *pFirst;
	*pFirst = (*pFirst)->next; 
	//free(del);
}

######删除给定结点
这里写图片描述
代码如下:

void ListErase(ListNode **pFirst, ListNode *pos)
{
	ListNode *del = NULL;
	ListNode *cur = NULL;
	assert(*pFirst != NULL);
	//如果给定结点不存在
	if(pos == NULL)
		return ;
	//如果给定结点是第一个元素 调用头删函数
	if(pos == *pFirst)
	{
		ListPopFront(pFirst);
		return ;
	}
	//如果给定结点是最后一个 调用尾删函数
	else if(pos->next == NULL)
	{
		ListPopBack(pFirst);
		return ;
	}
	//如果给定结点是除首尾外元素
	cur = *pFirst;
	while(cur->next != pos)
	{
		cur = cur->next;
	}
	cur->next = cur->next->next;
	//free(pos);
}

######删除指定元素
分为两种情况:
1、如果要删除元素是第一个元素,就调用头删函数;
2、如果要删除元素不是第一个元素,遍历该链表,找到第一个等于要删除元素的结点,将该结点的前一个结点的next指向该结点的下一个结点,即删除了该元素。
代码如下:

void ListRemove(ListNode **pFirst, DataType data)
{
	ListNode *cur = NULL;
	ListNode *del = NULL;
	assert(*pFirst != NULL);
	//如果删除的元素为第一个元素
	if((*pFirst)->data == data)
	{
		ListPopFront(pFirst);
		return ;
	}
	cur = *pFirst;
	while(cur != NULL)
	{
		if(cur->next->data == data)
		{
			del = cur->next;
			cur->next = cur->next->next;
			return ;
		}
		cur = cur->next;
	}
}

######删除所有指定元素
这里写图片描述

void ListRemoveAll(ListNode **pFirst, DataType data)
{
	ListNode *cur = NULL;
	assert(*pFirst != NULL);
	cur = *pFirst;
	while(cur != NULL)
	{
		if((*pFirst)->data == data)
		{
			*pFirst = (*pFirst)->next;
		}
		else if(cur->next->data == data)
		{
			cur->next = cur->next->next;
		}
		cur = cur->next;
	}
}

上述内容均为学习过程中的总结,如有不足之处,请指正

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值