数据结构-----【链表:基础】

news2025/1/16 3:54:26

链表基础

1、链表的理论基础

1)基础:

链表:通过指针串联在一起的线性结构,每个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一个节点的指针),最后一个指针域指向null(空指针的意思)。

链表的入口节点称为链表的头结点也就是head。

在这里插入图片描述

2)链表类型:

链表包括单链表、双链表、循环链表

单链表:指针域只能指向节点的下一个节点。

双链表:既可以向前查询也可以向后查询。

在这里插入图片描述

循环链表:链表首尾相连,循环链表可以解决约瑟夫环的问题。

在这里插入图片描述

3)链表的存储方式:

​ 数组在内存中是连续分布的,但是链表在内存中并不是连续分布的,链表通过指针域的指针连接在内存中的各个节点。例如:这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。

在这里插入图片描述

4)链表的定义:

这个单向链表中,正是因为我们定义了节点的构造函数,指明了可以把x丢给val,才可以在初始化的时候直接赋值。

//单链表
struct ListNode{
    int val;//数据
    ListNode* next;//指向下一个节点的指针
    ListNode(int x):val(x),next(NULL){} //节点构造函数
};
//为什么要自己写构造函数呢?c++可以自己生成构造函数
//通过自己定义构造函数初始化节点
ListNode* head = new ListNode(5);
//使用默认构造函数初始化节点,不能直接给变量赋值!!
ListNode* head = new ListNode;
head->val = 5;

5)链表的操作:

链表中要注意的就是是否更改原来指针!由项目引发的思考:不得不引入值传递和指针传递:

**传递值:**如果传递的是基本数据类型或结构体(而不是指针),则函数内对形参的修改不会影响外部的实际参数。

#include <stdio.h>

void modifyValue(int x) {
    x = x + 1;  // 修改的是 x 的副本,不会影响外部的实际参数
}

int main() {
    int a = 5;
    modifyValue(a);
    printf("%d\n", a);  // 输出 5,a 没有被修改
    return 0;
}

**传递指针:**如果传递的是指针,函数内对指针所指向的数据的修改会影响到外部的实际参数。但修改指针本身的值不会影响外部的指针。

#include <stdio.h>

void modifyPointer(int* ptr) {
    *ptr = *ptr + 1;  // 修改指针所指向的数据,会影响外部的实际参数
    ptr ++;      // 修改指针本身的值,不会影响外部的实际参数
}

int main() {
    int b = 10;
    int* p = &b;
    modifyPointer(p);
    printf("%d\n", *p);  // 输出 11,p 所指向的数据被修改
    return 0;
}

  • 递值时,函数内的修改不会影响外部的实际参数。

  • 传递指针时,函数内对指针所指向的数据的修改会影响外部的实际参数,但修改指针本身的值不会影响外部的指针。

1.打印链表

为了保险起见,还是可以在函数里面用临时变量保存链表值:

void SlistPrint(ListNode *phead){
    ListNode *cur = phead;
    while(!cur){
        printf("%d->", cur->data);
        cur = cur-> next;
    }
    printf("NULL\n");
}
2.清空链表:

好家伙不传入**pehead就要报错:

在这里插入图片描述

//一个结点的定义
typedef struct ListNode{
        int val;
        ListNode* next;
        //ListNode(int x):val(x),next(NULL){};//重构函数
}ListNode;


//因为要改变外部链表头的值,所以要传入**
//pphead 表示一个 ListNode 结构体的对象,而不是一个指针。在你的 SListClear 函数中,*pphead = NULL; 尝试将一个结构体对象设置为 NULL,这是不合法的。
//如果你的目的是通过函数清空链表并将外部传递的链表头指针设置为 NULL,你应该使用指向指针的指针,即 ListNode** pphead,并在函数内部通过解引用两次来修改外部传递的链表头指针的值。
void SListClear(ListNode **pphead)//**PPhead指向指针的指针
{
      ListNode *cur = *pphead;
      while(!cur){
          ListNode* temp = cur->next;
          free(cur);
          cur = temp;
      }
     *pphead = NULL;
}

int main(){
	ListNode* head = (ListNode*)malloc(sizeof(ListNode));
    head->val = 1;
    head->next = (ListNode*)malloc(sizeof(ListNode));
    head->next->val = 2;
    head->next->next = NULL;
	SListClear(&head);//注意这里是&相当于 **head
	  // 在这里 head 已经被设置为 NULL,链表被清空
    if (head == NULL) {
        printf("List is empty\n");
    }

    system("pause"); 
    return 0;
}

3.创建结点:
typedef struct ListNode{
        int val;
        ListNode* next;
        ListNode(int x):val(x),next(NULL){};//重构函数 C++可以直接写重构函数
}ListNode;

//等效于直接 ListNode* node = new ListNode(val);
ListNode* CreateListNode(int x){
    ListNode* NewNode = (ListNode*)malloc(sizeof(ListNode));
    ListNode->val = x;
    ListNode->next = NULL;
    return NewNode;
}


3.删除节点:

比如删除D节点:

首先将C节点的next指针指向E,然后再手动释放D节点(py有自己的内存回收机制,不用手动释放,但是c/c++最好手动释放)

特别注意:因为单链表的只能指向下一个节点,删除某个节点的时候指针是在这个节点前一个节点的位置的。

在这里插入图片描述

typedef struct ListNode{
        int val;
        ListNode* next;
        ListNode(int x):val(x),next(NULL){};
}ListNode;

ListNode* delete(ListNode * node){
	if(node->next!=NULL && node->next->next!=NULL){
		node->next = node->next->next;
	}
	return node;
}
4、添加节点:

​ 在C和D中添加节点,让C的指针域指向F,再把F的指针域指向D。(添加不需要释放内存)

​ 链表的增添和删除都是O(1)操作,也不会影响到其他的节点,但是查找的时间复杂度可能是O(n)(一个一个next指针进行查找)。

typedef struct ListNode{
        int val;
        ListNode* next;
        ListNode(int x):val(x),next(NULL){};
}ListNode;

ListNode* add(ListNode * node,int val){
	ListNode* tmp = new ListNode(val);
	temp->next = node->next;
	node->next = temp;
	return node;
}

4.数组和链表的对比

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1885910.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重塑电商版图:全民拼购的崛起与魅力

在数字化浪潮的推动下&#xff0c;电子商务领域正经历着前所未有的变革&#xff0c;其中&#xff0c;全民拼购作为一种创新的电商玩法&#xff0c;正逐步成为市场的新宠。本文旨在深入探讨全民拼购的核心理念、运作机制、独特优势及其引人入胜的参与方式&#xff0c;为行业内外…

如何挑选适合的无线模块?哪些方面值得关注

市场上的无线模块种类繁多&#xff0c;如LoRa模块&#xff0c;WiFi模块&#xff0c;蓝牙模块&#xff0c;UWB模块等涵盖了各种不同的通信标准和应用需求&#xff0c;为满足模块的特定需求并能实现模块最大的性能价值&#xff0c;那么在选择无线模块的时候可以考虑以下几个方面。…

跟我练习100道FPGA入门题目~(1/100)

难度指数&#xff1a;一颗星 关键词&#xff1a;组合逻辑、入门基础 题目介绍&#xff1a; 多路选择器又称为数据选择器&#xff0c;请参考真值表设计一个二选一多路选择器。 其中s为控制信号&#xff0c;d0&#xff0c;d1为两个输入信号&#xff0c;y为输出信号。当s为低电…

金蝶云星空字段之间连续触发值更新

文章目录 金蝶云星空字段之间连续触发值更新场景说明具体需求&#xff1a;解决方案 金蝶云星空字段之间连续触发值更新 场景说明 字段A配置了字段B的计算公式&#xff0c;字段B配置了自动C的计算公式&#xff0c;修改A的时候&#xff0c;触发了B的重算&#xff0c;但是C触发不…

如何利用GPT-4o生成有趣的梗图

文章目录 如何利用GPT-4o生成有趣的梗图一、引言二、使用GPT-4o生成梗图1. 提供主题2. 调用工具3. 获取图片实际案例输入输出 三、更多功能1. 创意和灵感2. 梗图知识 四、总结 如何利用GPT-4o生成有趣的梗图 梗图&#xff0c;作为互联网文化的一部分&#xff0c;已经成为了我们…

怎么找到DNS服务器的地址?

所有域都注册到域名名称服务器&#xff08;DNS&#xff09;点&#xff0c;以解析域名应指向的IP地址。此查找类似于在查找个人名称并查找其电话号码时的电话簿如何运行。如果DNS服务器设置错误或指向错误的名称服务器&#xff0c;则域可能无法加载相应的网页。 如何查找当前的…

nginx.conf的配置文件

nginx.conf 1.全局模块 worker_processes 1 工作进程数&#xff0c;设置成服务器内核数的2倍&#xff08;一般不超过8个&#xff0c;超过8个会降低性能4个 1-2个&#xff09; 处理进程的过程必然涉及配置文件和展示页面&#xff0c;也就是涉及打开文件的数量。 linux默认打…

一键AI抠图太方便啦!不会ps也能成为修图大师

引言 在数字生活中&#xff0c;抠图技能已成为一项日常且必不可少的技能。无论是需要更换证件照的背景色&#xff0c;还是想要将图像中的主体精确分离。 但并非所有人都精通Photoshop&#xff0c;而且对于简单的任务来说&#xff0c;使用Photoshop可能显得过于复杂。因此&…

手机数据恢复篇:如何在恢复出厂设置后的 iPhone 恢复短信

您可能会认为&#xff0c;在恢复出厂设置iPhone后恢复短信时&#xff0c;一切都会丢失&#xff0c;但是仍然有一些方法可以检索您的重要对话。截至 2024 年&#xff0c;数据恢复技术的进步使得从备份甚至直接从设备内存中抢救消息变得更加容易。无论是通过 iCloud、iTunes 还是…

【大数据】什么是数据融合(Data Fusion)?

目录 一、数据融合的定义 二、数据融合的类型 三、数据融合的挑战 四、数据融合的方法 五、数据融合的关键环节 1.数据质量监控指标的制定和跟踪 2.异常检测和处理机制 3.实时数据监测与反馈机制 4.协同合作与知识共享 一、数据融合的定义 数据融合&#xff08;Data Fusion&…

【linux】网络基础(2)——udp协议

文章目录 引言udp协议的特点udp的头部结构UDP的工作原理简单的UDP网络程序套接字的认识udp服务端代码udp客户端代码服务端运行 引言 用户数据报协议&#xff08;User Datagram Protocol, UDP&#xff09;是一种无连接的传输层协议。它是因特网协议家族的一部分&#xff0c;定义…

武汉星起航:无锡跨境电商加速“出海”,物流升级助品牌全球布局

随着全球化的不断深入&#xff0c;跨境电商作为数字外贸的新业态&#xff0c;正逐渐成为无锡企业拓展海外市场的重要渠道。武汉星起航关注到&#xff0c;近年来&#xff0c;无锡市通过积极推进国际物流枢纽建设&#xff0c;完善海外仓布局&#xff0c;以及各特色产业带的积极参…

《单片机》期末考试复习-学习笔记总结

题型 问答题(15分)编程题(65分)编程题1(20分)编程题2(45分)设计题(20分)一、问答题 1.1.单片机概念和特点 1.2. 51单片机的中断结构 1.3.主从式多机通讯的概念及其工作原理 多机通信是指两台以上计算机之间的数据传输,主从式多机通信是多机通信系统中最简单的一种,…

Graspnet复现笔记

前言 参考文章&#xff1a;Baseline model for "GraspNet-1Billion: A Large-Scale Benchmark for General Object Grasping" (CVPR 2020).[paper] [dataset] [API] [doc] 代码仓库&#xff1a;https://github.com/graspnet/graspnet-baseline 一、确定配置 Ubunt…

基于springboot的校园商铺管理系统

功能结构图&#xff1a; 实现图&#xff1a; 后台功能&#xff1a; 商品管理 公告管理 前台页面 详情 订单 我的订单

【热门会议|稳定检索】2024年食品安全与生物技术国际会议(ICFSB 2024)

2024年食品安全与生物技术国际会议&#xff08;ICFSB 2024&#xff09; 2024 International Conference on Food Safety and Biotechnology 【重要信息】 大会地点&#xff1a;贵阳 大会官网&#xff1a;http://www.icicfsb.com 投稿邮箱&#xff1a;icicfsbsub-conf.com 【注…

从深度学习到音乐创作:AI如何重新定义音乐行业

&#x1f4d1;引言 近一个月来&#xff0c;随着几款音乐大模型的轮番上线&#xff0c;AI在音乐产业的角色迅速扩大。这些模型不仅将音乐创作的门槛降至前所未有的低点&#xff0c;还引发了一场关于AI是否会彻底颠覆音乐行业的激烈讨论。从初期的兴奋到现在的理性审视&#xff0…

ShareSDK HarmonyOS NEXT集成指南

集成前准备 注册账号 使用MobSDK之前&#xff0c;需要先在MobTech官网注册开发者账号&#xff0c;并获取MobTech提供的AppKey和AppSecret&#xff0c;详情可以点击查看注册流程 ShareSDK流程图 集成配置 添加依赖 在Terminal窗口中&#xff0c;执行如下命令进行安装 ohpm …

书城在线系统:基于Java和SSM框架的高效信息管理平台

开头语&#xff1a;你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM框架&#xff08;Spring, Spring MVC, Mybatis&#xff09; 工具&…