iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言数据结构与算法之单链表
  • 123
分享到

C语言数据结构与算法之单链表

2024-04-02 19:04:59 123人浏览 独家记忆
摘要

目录基本概念读取数据元素获取第i个结点的数据元素插入数据元素 初始化链表打印链表顺序表查空顺序表的删除 删除第i个结点及其数据元素情况1:当删除的是第一个元素情况2:除第一个结点外完

基本概念

链表的每一个结点中只包含一个指针域

优点 : 储存空间利用高效

举例来说:


typedef struct student{
	int id;		//学生编号
	char* name; //学生名称
 
	//指向下一结点的指针
	struct Student* pNext;
}Student;

与之相反的是多链表


typedef struct student{
	int id;		//学生编号
	char* name; //学生名称
 
	//指向下一结点的指针
	struct Student* pNext;
	struct Student* qNext;
}Student;

读取数据元素

获取第i个结点的数据元素

  1. 声明一个结点指针p指向链表的第一个结点a1,初始化j从1开始
  2. 当j < i 时,遍历链表,让p的指针向后移动,不断指向下一个结点,j 累加 1
  3. 当链表末尾 p 为空时,则说明第 i 个元素不存在;否则查找成功,返回结点 p 的数据

 

1.定义数据元素


//定义数据元素
typedef struct student{
	int id;		
	char* name; 
}ElementType;

2.定义顺序表结构


typedef struct {
	ElementType dates[MAX_SIZE];   //当前顺序表中的数据集合
	int length;					   //当前顺序表中的元素个数
 
}SeqList;

3.定义链表的结点(包括数据域和指针域)


typedef struct node {
	ElementType date;  //数据域
	struct Node* node; //指针域,指向下一个结点
}Node;

4.设置头结点

我们在定义链表时,习惯性的会定义头结点,以便统一链表结点的插入和删除操作


typedef struct Linklist {
	Node* next;  //头指针
	int length;
}Linklist;

如果链表有头结点,next就指向头结点,没有就指向第一个结点

链表的长度初始值为0

插入数据元素 

在第i个结点后插入数据元素  

  1. 创建一个空节点,分配内存空间,设置数据元素
  2. 获取第i个结点,设置新结点的后继结点为该结点的后继结点
  3. 设置第i个结点的后继结点为该结点

1.创建空节点并为数据域赋值


	//创建空节点并为数据赋值
	Node* node = (Node*)malloc(sizeof(Node));
    node -> date = element;
    node -> next = NULL;

2.通过循环找到要插入的结点


	for (int i = 1; currNode && i < pos - 1; i++)
	{
		currNode = currNode->next;
	}

3.将结点插入并对接前面的结点


	if (currNode) {
		node->next = currNode->next;
		currNode->next = node;
		linkList->length++;
	}

初始化链表


void InitLinkList(LinkList* linkList, ElementType* dateArrar, int length)
{
	for (int i = 0; i < length; i++) {
		InsertLinkList(linkList, i + 1, dateArrar[i]);
	}
}

打印链表


void PrintLinkList(LinkList* linklist)
{
	Node* node = linklist->next;
	if (!node)
	{
		printf("链表为空!\n");
		linklist->length = 0;
		return 0;
	}
	for (int i = 0; i < linklist->length; i++) {
		printf("%d\t%s\t\n", node->date.id, node->date.name);
        node = node->next;
	}
}

顺序表查空


int IsLinkListEmpty(LinkList* linkList) {
 
	return linkList->length == 0 ? TRUE : FALSE;
 
}

顺序表的删除 

删除第i个结点及其数据元素

  1. 获取第i个结点,若该结点不是第一个结点,则获取第i - 1个结点
  2. 将第i -1个结点的后缀结点设为第i个结点的后缀结点
  3. 删除第i个结点,释放内存空间,记录并返回删除数据元素的值

情况1:当删除的是第一个元素


	if (pos == 1)
	{
		node = linkList->next;
		if (node) {
			element = node->date;
			linkList->next = node->next;
			free(node);  //释放被删除的结点
			linkList->length--;
		}
        return element;
	}

情况2:除第一个结点外

  1. 找到要删除的结点和他的前缀结点
  2. 要删除结点的next 赋值给前缀结点
  3. 释放要删除的结点

	Node* preNode; //前缀结点
	node = linkList->next;
	for (int i = 1; node && i < pos; i++)
	{
		preNode = node;
		node = node->next;
	}
	if (node)
	{
		element = node->date;
		preNode->next = node->next;
		free(node);
		linkList->length--;
	}
	return element;

完整代码


ElementType DeleteLinkListElement(LinkList* linkList, int pos)
{
	ElementType element;   //被删除的元素
	element.id = -999;     //赋一个不可能的值,来判断删除是否成功
	Node* node = NULL;
 
	if (pos == 1)
	{
		node = linkList->next;
		if (node) {
			element = node->date;
			linkList->next = node->next;
			free(node);  //释放被删除的结点
			linkList->length--;
		}
	}
 
	Node* preNode; //前缀结点
	node = linkList->next;
	for (int i = 1; node && i < pos; i++)
	{
		preNode = node;
		node = node->next;
	}
	if (node)
	{
		element = node->date;
		preNode->next = node->next;
		free(node);
		linkList->length--;
	}
	return element;
 
}

删除单链表整表

  1. 声明结点p 和 q
  2. 将第一个结点赋值给p
  3. 循环将下一个结点赋值给q,释放p,将q赋值给p

 


void CleatLinkList(LinkList* linkList)
{
	Node* node = linkList->next;
	Node* nextNode;
	while (node) {
		nextNode = node->next;  //先记录当前结点的下一个结点,以便释放当前结点的内存
		free(node);
		node = nextNode;
	}
	linkList->next = NULL;
	linkList->length = 0;
}

单链表VS顺序表

 

 

以上就是C语言数据结构与算法之单链表的详细内容,更多关于C语言单链表的资料请关注编程网其它相关文章!

--结束END--

本文标题: C语言数据结构与算法之单链表

本文链接: https://www.lsjlt.com/news/160680.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c语言怎么计算字符串长度
    在C语言中,可以使用内置的strlen()函数来计算字符串的长度。该函数位于string.h头文件中。以下是一个示例代码: #inc...
    99+
    2024-05-15
    c语言
  • c语言怎么判断三个数的大小
    可以通过比较三个数之间的大小关系来判断它们的大小。以下是一个示例代码: #include <stdio.h> int ...
    99+
    2024-05-15
    c语言
  • c++排序函数sort怎么使用
    在C++中,使用sort函数对容器中的元素进行排序,可以按照默认的升序排列,也可以自定义排序规则。 下面是一个简单的例子,对一个ve...
    99+
    2024-05-15
    c++
  • c++中string的compare函数怎么使用
    在C++中,可以使用string的compare函数来比较两个string对象的大小。该函数的原型如下: int compare(c...
    99+
    2024-05-15
    c++
  • c++中string的compare函数有什么用
    c++中string的compare函数用于比较两个字符串的大小关系。该函数返回一个整数值,表示两个字符串的比较结果。 具体来说,如...
    99+
    2024-05-15
    c++
  • c++中print函数的功能有哪些
    在C++中,通常使用std::cout来进行输出操作,而不是使用print函数。std::cout是C++标准库中的一个输出流对象,...
    99+
    2024-05-15
    c++
  • c语言数据结构怎么使用
    在C语言中,数据结构可以通过定义结构体来实现。以下是一些常见的数据结构的使用方法示例: 链表: #include <std...
    99+
    2024-05-15
    c语言
  • c++中print函数的用法是什么
    在C++中没有内置的print函数,但可以使用cout来输出内容到控制台。cout是C++标准库中的一个输出流对象,可以使用<...
    99+
    2024-05-15
    c++
  • c++中concept的用法是什么
    在C++20中,Concept是一种新的语言特性,用于定义类型要求和约束。Concept可以被用来约束函数模板、类模板和普通函数的参...
    99+
    2024-05-15
    c++
  • c++中concept的作用是什么
    在C++中,concept的作用是定义一种通用的约束,用于限制模板参数的类型范围。通过使用concept,可以在编译时对模板参数进行...
    99+
    2024-05-15
    c++
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作