当前位置: 首页 > article >正文

C语言模拟实现简单链表的复盘

代码引用自下面这个链接

https://blog.csdn.net/liyuanyue2017/article/details/83214908?fromshare=blogdetail&sharetype=blogdetail&sharerId=83214908&sharerefer=PC&sharesource=lfm147258369&sharefrom=from_link

自己实现

#include <stdio.h>
#include <malloc.h>

typedef int ElementType;//ElementType可以是任意类型
typedef struct LNode* List;
typedef struct LNode
{
	ElementType data;//数据域
	List next;//链表下一个元素地址
}LNode;
List L;

List Empty();//初始化链表
int Lenth(List L);//以遍历的方式求表长
List FindKth(int k, List L);//按序号查找
List Find(ElementType X, List L);//按值查找
List Insert(ElementType X, int i, List L);//插入第i个元素
List Delete(int i, List L);//删除第i个节点
void Print(List L);//打印链表
//初始化链表
List Empty()
{
	List L = (List)malloc(sizeof(struct LNode));
	L = NULL;
	return L;
}

//求表长
int Length(List L)
{
	List p = L;
	int count = 0;
	while (p)//当p不为空
	{
		p = p->next;
		count++;
	}
	return count;
}
//按序查找
List FindKth(int k, List L)
{
	List p = L;
	int i = 1;//从第一个元素开始找
	while (p && i < k)
	{
		p = p->next;
		i++;
	}
	if (i == k)
	{
		return p;//找到了
	}
	else
	{
		return NULL;//找不到
	}
}

//按值查找
List Find(ElementType X, List L)
{
	List p = L;
	while (p && p->data != X)
	{
		//如果找到了就返回那个元素的地址为p
		//找不到那个元素也就没有它的地址,所以返回的就是NULL
		p = p->next;
	}
	return p;

}

//插入第i个元素
List Insert(ElementType X, int i, List L)
{
	List p;
	List s;

	if (i == 1)//新节点插入在表头
	{
		List s = (List)malloc(sizeof(struct LNode));
		s->data = X;
		s->next = L;
		return s;//此时插入的节点s为头节点
	}
	else
	{
		p = FindKth(i - 1, L);//查找要删除的前一个元素
		if (!p)//如果p不存在
		{
			printf("节点错误\n");
			return NULL;
		}
		else
		{
			s = (List)malloc(sizeof(LNode));
			s->data = X;
			s->next = p->next;
			p->next = s;
			return L;
		}
	}
}

List Delete(int i, List L)
{
	List p;
	List s;
	if (i == 1)
	{
		s = L;
		if (L)//如果头节点不为空
			L = L->next;
		else
			return NULL;
		free(s);
		return L;
	}
	p = FindKth(i - 1, L);
	if (!p || !p->next)
	{
		printf("节点错误\n");
		return NULL;
	}
	else
	{
		s = p->next;
		p->next = s->next;
		free(s);
		return L;
	}

}

void Print(List L)
{
	List t;
	int flag = 1;
	printf("当前链表为:");
	for (t = L; t; t = t->next)
	{
		printf("%d ", t->data);
		flag = 0;
	}
	if (flag == 1)
	{
		printf("NULL\n");
	}
}


int main()
{
	L = Empty();
	Print(L);
	L = Insert(11, 1, L);
	Print(L);

	L = Insert(25, 1, L);
	Print(L);

	L = Insert(33, 2, L);
	Print(L);

	L = Insert(77, 3, L);
	Print(L);

	Print(L);
	printf("当前链表长度为:%d\n", Length(L));
	printf("此时链表中第二个结点的值是:%d\n", FindKth(2, L)->data);
	printf("查找22是否在该链表中:");
	if (Find(22, L))
		printf("是!\n");
	else
		printf("否!\n");
	printf("查找33是否在该链表中:");
	if (Find(33, L))
		printf("是!\n");
	else
		printf("否!\n");
	L = Delete(1, L);
	L = Delete(3, L);
	printf("----------删除后-----\n");
	Print(L);
	return 0;
}

指针的错误使用

我在实现时,错误讲指针先赋值为NULL,这样的话会造成野指针错误。

计算节点大小的错误

sizeof(struct LNode)更加严谨

链表跳到下一个节点

不是将指针赋值给一个变量然后++,是将指针赋值为下一个节点的指针。

在插入,删除时总是忽略插入为头节点的情况

头节点与其他节点的处理方式不同

在插入删除时,没有对前一个节点或者当前节点进行判断,如果为非法节点,应该停止。


http://www.kler.cn/a/417716.html

相关文章:

  • 【Linux网络编程】:URL(encode),HTTP协议,telnet工具
  • 游戏引擎学习第88天
  • 留学生编程辅导Haskell/OCaml/Prolog/Rust/Python
  • 使用SpringBoot发送邮件|解决了部署时连接超时的bug|网易163|2025
  • SQL范式与反范式_优化数据库性能
  • 为AI聊天工具添加一个知识系统 之77 详细设计之18 正则表达式 之5
  • 【机器学习算法】XGBoost原理
  • 【故障处理系列--业务官网无法打开】
  • 0017. shell命令--tac
  • Milvus的索引类型
  • 【经典论文阅读】Transformer(多头注意力 编码器-解码器)
  • 打造高质量技术文档的关键要素(结合MATLAB)
  • selinux、firewalld
  • JD - HotKey:缓存热 Key 管理的高效解决方案
  • Vue + Vite + Element Plus 与 Django 进行前后端对接
  • 【系统架构设计师】高分论文:论敏捷软件开发方法及其成用
  • TYUT设计模式大题
  • 架构04-透明多级分流系统
  • LeetCode-315. Count of Smaller Numbers After Self
  • 解决因为数据变化,页面没有变化的情况 , 复习一下使用 vuex 的 modules
  • C#里怎么样使用Array.BinarySearch函数?
  • LeetCode题练习与总结:最小基因变化--433
  • 【踩坑】git中文乱码问题
  • 从0开始边做边学,用vue和python做一个博客,非规范化项目,怎么简单怎么弄,跑的起来有啥毛病解决啥毛病(一)
  • IIS管理器、Sql Server、windows操作系统,nginx
  • 【前端】JavaScript中的字面量概念与应用详解