基于C语言-单链表-增删查改等功能实现

1. 创建结构体
typedef struct LNode
{
	/*
		单链表
		 LNode     表示单个结点
	*/
	ElemType data;
	struct LNode *next;
}LNode;
2. 定义增加新节点(动态申请空间)的函数createLinkListNode
LNode *creatLinkListNode(ElemType element)
{
	/*
		新增一个结点
	*/
	LNode *newNode = (LNode *)malloc(sizeof(LNode));
	if (newNode == NULL)
	{
		printf("申请空间失败!!!\n");
	}else{
		newNode->data = element;
		newNode->next = NULL;
	}

	return newNode;
}
3. 单链表的头部增加元素
void LinkListPushFront(LNode **ListHead, ElemType element)
{
	/*
		单链表头插元素
	*/
	LNode *newNode = creatLinkListNode(element);	//开辟一个新的结点
	newNode->next = *ListHead;						//指向链表头结点
	*ListHead = newNode;							//将头指针指向新的头结点
}
4. 单链表头部删除元素
void LinkListPopFront(LNode **ListHead)
{
	/*
		单链表删除头结点
	*/
	//1. 空链表
	if (*ListHead == NULL)
	{
		return;
	}
	//2. 只有一个结点的单链表 + 3. 有两个及以上结点的单链表
	else{
		LNode *tamp = (*ListHead)->next;
		free(*ListHead);
		*ListHead = tamp;
	}
}
5. 单链表尾部增加元素
void LinkListPushBack(LNode **phead, ElemType element)
{
	/*
		向单链表尾插一个新结点,存储值x
	*/
	LNode *tail = *phead;
	LNode *newNode = creatLinkListNode(element);
	if (*phead == NULL)
	{
		//指向的单链表为空
		*phead = newNode;

	}else{

		//指向的单链表不为空
		while (tail->next != NULL)
		{
			//找到尾结点
			tail = tail->next;
		}
		//newNode = creatLinkListNode(element);
		//插入新结点到单链表表尾
		tail->next = newNode;

	}
}
6. 单链表尾部删除元素
void LinkListPopBack(LNode **phead)
{
	/*
		删除单链表尾部结点
	*/

	//1. 链表为空
	if (*phead == NULL)
	{
		return;
	}
	//2. 只有一个结点
	else if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	//3. 有两个及以上结点
	else{
		LNode *tail = *phead;
		LNode *prev = NULL;
		while(tail->next != NULL)
		{
			prev = tail;		//存储前一个结点地址的指针
			tail = tail->next;
		}
		free(tail);
		tail = NULL;		//此步骤可写可不写,写上好习惯。因为是临时变量,和上面的2的情况不一样。
		prev->next = NULL;
	}

}
7. 单链表指定位置增加元素
void LinkListInsert(LNode **List, int position, ElemType element)
{
	/*
		单链表指定位置插入元素
	*/
	//判断插入位置的合法性
	if (position > GetLenghth(*List) || position < 1)
	{
		printf("查出链表范围,请输入合法的位置插入元素!\n");
	}else{
		LNode *newNode = creatLinkListNode(element);
		LNode *pos = *List;	//在以下"2."部分中查找位置并插入时使用此临时指针,
							//不可直接用头指针,位置会发生改变,导致链表发生改变
		int tamp = 0;
		//1. 插入位置为头部
		if (position - 1 == 0)
		{
			newNode->next = *List;
			*List = newNode;
		}
		//2. 插入位置不为头部
		else{
			while (position - 2 != tamp)
			{
				//找到插入位置前一个结点
				tamp++;
				pos = pos->next;
			}
			newNode->next = pos->next;
			pos->next = newNode;
		}
	}
}
8. 单链表指定位置删除元素
void LinkListDeleteNode(LNode **List, int position)
{
	/*
		删除指定位置结点及元素
	*/
	//1. 空链表
	if ((*List) == NULL)
	{
		printf("此链表为空,无可删除结点。\n");
	}
	//2. 非空链表
	else if (position > GetLenghth(*List) || position < 1)
	{
		//判断合法性
		printf("超出范围,请输入合法位置!\n");
	}
	else{
		//2.1 删除位置为头部
		if (position - 1 == 0)
		{
			LNode *tamp = (*List)->next;	//释放头指针指向的空间后会变成野指针,
											//需要通过tamp将其拉回链表中,变回头指针。
			free(*List);
			*List = tamp;
		}
		//2.2 删除位置不为头部
		else{
			int i = 0;
			LNode *sreachPosition = *List;
			LNode *PrePosition;
			while(position - 1 != i)
			{
				i++;
				PrePosition = sreachPosition;
				sreachPosition = sreachPosition->next;
			}
			PrePosition->next = sreachPosition->next;
			free(sreachPosition);
			sreachPosition->next = NULL;
		}
	}
}
9. 单链表查询元素
void LinkListSreach(LNode *ListHead, ElemType element)
{
	/*
		单链表查找元素
	*/
	LNode *cur = ListHead;
	int num = 0;
	while (cur)
	{
		if (cur->data == element)
		{
			//找到指定的元素则返回
			printf("所查找的元素\"%d\"在链表的第%d位置.\n", element, num+1);
			break;
		}
		//未找到指向下一个结点
		cur = cur->next;
		num++;
	}
	//走到此步说明所要查找的元素不存在
	if (cur == NULL)
	{
		printf("查找元素不存在!!\n");
	}
}
10. 单链表更改指定位置的元素
void LinkListChangeElement(LNode *List, int position, ElemType newElement)
{
	/*
		单链表改变指定位置的元素
	*/
	int i = 0;
	int ListLenght = GetLenghth(List);
	if (position > ListLenght || position < 1)
	{
		printf("请输入正确的位置修改元素!!\n");
	}
	else{
		while (1)
		{
			if (position-1 == i)
			{
				List->data = newElement;
				break;
			}
			i++;
			List = List->next;
		}
		printf("修改元素成功!!\n");
	}
}
11. 单链表返回链表长度
int GetLenghth(LNode *LinkList)
{
	/*
		获取链表的长度
	*/
	int num = 0;
	while (LinkList != NULL)
	{
		LinkList = LinkList->next;
		num++;
	}
	return num;
}
  1. 打印单链表
void LinkListPrint(LNode *phead)
{
	/*
		遍历并打印链表中的值
	*/
	LNode *cur = phead;
	while (cur != NULL)
	{
		//一致遍历到尾指针
		printf("%d -> ", cur->data);
		cur = cur->next;
	}
	printf("null\n");		//单链表最后一个结点指向的空值
}
12. 功能测试
int main()
{
	//定义单链表
	LNode *Liste = NULL;
	LNode *emptyLinkList = NULL;

	//尾插新元素
	LinkListPushBack(&Liste, 1);
	LinkListPushBack(&Liste, 2);
	LinkListPushBack(&Liste, 3);

	//遍历单链表并打印data
	LinkListPrint(Liste);

	//尾部删除元素
	LinkListPopBack(&Liste);

	//遍历单链表并打印data
	LinkListPrint(Liste);

	//头插新元素
	LinkListPushFront(&Liste, 725);

	//遍历单链表并打印data
	LinkListPrint(Liste);

	//头删新元素
	LinkListPopFront(&Liste);

	//遍历单链表并打印data
	LinkListPrint(Liste);

	//查找元素
	LinkListSreach(Liste, 2);
	LinkListSreach(Liste, 725);

	//获取链表长度
	printf("链表长度为%d\n", GetLenghth(Liste));


	//改变指定位置的元素
	LinkListChangeElement(Liste, 2, 12);
	LinkListChangeElement(Liste, 1, 711);
	LinkListChangeElement(Liste, 0, 111);
	LinkListChangeElement(Liste, 3, 222);

	//指定位置插入元素
	LinkListInsert(&Liste, 2, 33);
	LinkListInsert(&Liste, 1, 22);
	LinkListInsert(&Liste, 4, 91);

	//遍历单链表并打印data
	LinkListPrint(Liste);

	//指定位置删除元素
	LinkListDeleteNode(&Liste, 1);

	//遍历单链表并打印data
	LinkListPrint(Liste);

	//指定位置删除元素
	LinkListDeleteNode(&Liste, 2);
	LinkListDeleteNode(&Liste, 3);

	//遍历单链表并打印data
	LinkListPrint(Liste);

	//指定位置删除,空链表version test
	LinkListDeleteNode(&emptyLinkList, 1);

	return 0;
}

测试结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值