链表——C语言——day17

news/2025/3/14 23:04:24/

链表

链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。在用数组存放数据时,必须事先定义固定的长度(即元素个数)。链表则没有这种缺点,它根据需要开辟内存单元。
在这里插入图片描述
链表有一个“头指针“变量,图中以 head 表示,它存放一个地址,该地址指向一个元素。链表中每一个元素称为"结点",每个结点都应包括两个部分:用户需要用的实际数据和下一个结点的地址,也称为数据域和指针域。可以看出,head 指向第一个元素;第一个元素又指向第二个元素……直到最后一个元素,该元素不再指向其他元素,它称为”表尾”,它的地址部分放一个"NULL"( 表示"空地址"),链表到此结束。

链表中各元素在内存中可以不是连续存放的。要找某一元素,必须先找到上一个元素,根据它提供的下一元素地址才能找到下一个元素。如果不提供“头指针”(head),则整个链表都无法访问。

我们可以这样设计结构体类型:

struct student 
{	int num; float score;struct student * next;
};

其中成员num和score用来存放结点中的有用数据(用户需要用到的数据),相当于上图结点中的 A,B,C,D。next 是指针类型的成员,它指向 struct student 类型数据(这就是next 所在的结构体类型)。一个指针类型的成员既可以指向其他类型的结构体数据,也可以指向自己所在的结构体类型的数据。现在,next是struct student 类型中的一个成员,它又指向struct student 类型的数据。用这种方法就可以建立链表。
在这里插入图片描述

建立链表

首先,链表分为有头链表和无头链表

在这里插入图片描述

在本文章中,我们主要研究“有头单向链表”

空链表 ——代表头节点的next指针指NULL

void initList(struct Node *pHead)
{pHead->next = NULL;
}

链表的插入

在这里插入图片描述

头插法

step1:首先是创建新节点
struct Node *pNew = malloc (sizeof(struct Node));
pNew->data = 100;
step2:将新节点插入链表
struct Node *pNew= malloc(sizeof(stiuct Node));
pNew->data= 100;
(1).pNew->next = pHead->next;
(2).pHead->next = pNew;
在这里插入图片描述

我们可以将头插法函数写成这样:
void pushFront(struct Node *pHead,int n)
{struct Node *pNew = malloc (sizeof(struct Node));  // 在堆上创建空间pNew->data= n;  //输入新节点的数据pNew->next = pHead->next;	//将头节点的指针域上的地址赋值给新节点指针域pHead->next = pNew;	//头节点的指针域上的地址指向新节点
}
尾插法

step1:首先是创建新节点
step2:定位到尾节点

定位到尾节点:
while(p->next != NULL)
{
p = p->next;
}

step3:将新节点插入链表
在这里插入图片描述
但是,我们需要考虑如果链表本身是个空链表,怎么尾插?并且还需要判断链表是否为空?
所以,我们将尾插法可以写成这样:

int isEmpty(struct Node *pHead) //判断链表是否为空链表
{return pHead->next == NULL;
}void pushBack(struct Node *pHead, int n)
{if(isEmpty(pHead)){pushFront(pHead, n);	//空的话直接使用头插法}else{struct Node *pNew= mallcc(sizeof(struct Node));pNew->data=n;struct Node *p = pHead->next;while(p->next){p = p->next;}p->next = pNew;pNew->next = NULL;}
}
链表遍历

在这里插入图片描述
只要p不为NULL,直接输出数据即可。

void printList(struct Node *pHead)
{struct Node *p;p =pHead->next;while(p != NULL){printf("&d\n", p->data);p = p->next;}
}
计算链表中有效节点的个数
size_t length(struct Node *pHead)
{size_t ret =0;struct Node *p= pHead->next;while(p){++ret;p = p->next;}return ret;
}
头删法

在删除的时候,我们首先要确定链表是否为空,若链表为空,则不能删除。
在这里插入图片描述
首先,头节点的地址域指针指向p->next的地址,随后释放p即可。

void popFront(struct Node *pHead)
{if(!isEmpty(pHead)){struct Node *p= pHead->next;pHead->next = p->next;free(p);}
}
尾删法

在这里插入图片描述
我们首先要判断链表是否为空,为空的话直接结束,随后判断链表中是否至少有两个以上的有效节点,如果只有一个节点,直接转到头删法即可。

void popBack(struct Node *pHead)
{if(!isEmpty(pHead))	//判断是否为空链表{if(length(pHead)== 1) 	//判断有几个节点{popFront(pHead);}else{struct Node *p= pHead->next;while(p->next->next != NULL){p = p->next;}free(p->next);p->next = NULL;}}
}
链表销毁
void destroyList(struct Node *pHead)
{while(!isEmpty(pHead)){popBack(pHead);popFront(pHead);}
}

以上就是链表的常见操作。


http://www.ppmy.cn/news/1340770.html

相关文章

python爬虫4

#1.练习 # (1) 获取网页的源码 # (2) 解析 解析的服务器响应的文件 etree.HTML # (3) 打印 import urllib.request urlhttps://www.baidu.com/ headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit…

在vue3中,组件的script setup 里如何理解 v-model 参数

在Vue 3中,可以使用defineEmits和defineProps函数来定义组件的v-model。defineEmits函数用于定义组件的事件,而defineProps函数用于定义组件的属性。 以下是一个示例: import { defineComponent, defineEmits, defineProps } from vue;cons…

【Midjourney】新手指南:参数设置

1.--aspect 或 --ar 用于设置图片长宽比,例如 --ar 16:9就是设置图片宽为16,高为9 2.--chaos 用于设置躁点,噪点值越高随机性越大,取值为0到100,例如 --chaos 50 3.--turbo 覆盖seetings的设置并启用极速模式生成…

服务器为什么老是被攻击?被攻击了怎么办?

1、关闭端口,只打开必要的端口 服务器端口是攻击的主要入口,是服务器的外部窗口。服务器上的开放端口被黑客使用,他们通过这些开放端口攻击服务器。相对有效的预防方法是关闭一些不必要的端口,然后修改关键端口。如果你少开一个开…

银行数据仓库体系实践(16)--数据应用之财务分析

总账系统 在所有公司中,财务分析的基础都是核算,那在银行的系统体系中,核算功能在业务发生时由业务系统如核心、贷款、理财中实现登记,各业务系统会在每天切日后统计当天各机构的核算科目的发生额与余额,并统一送到总账…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextPicker组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextPicker组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、TextPicker组件 TextClock组件通过文本将当前系统时间显示在设备上。支持不…

C/C++ C++入门

个人主页:仍有未知等待探索-CSDN博客 专题分栏:C_仍有未知等待探索的博客-CSDN博客 目录 一、C关键字 二、命名空间 1、区别 1. C语言 ​编辑 2. C 2、命名空间定义 3、命名空间的使用 三、C输入&输出 四、缺省参数 五、函数重载 六、引用 …

函数重载你真的了解吗?

1.什么叫函数重载? 函数重载(Function Overloading)是指在同一个作用域内,允许定义多个具有相同名称但参数列表不同的函数。具体而言,函数重载允许你定义同名的函数,但这些函数应该有不同的参数类型、参数个…