1.2.1-2部分数据结构的说明02_链表

news2025/1/10 4:18:07

(1)链表数据结构:

概念:

将列表中相互连接的节点不连续的存储在内存中。与数据不同,我们无法再恒定时间内访问任何元组,如果遍历所有则花费时间与元素总数n成正比。插入和删除1个元素的时间复杂度都是O(n)。链表中每个块成为一个节点,每个节点有两个字段,一个存储数据,另一个存储下一个节点的地址(链接字段)。

特点:

(1) 每个节点由2个字段构成,1个存储数据,另1个存储下一个节点的地址。

(2) 下一个节点的名称与上一个节点的link一致。

(3)存整数型的数组(array)占4字节,而链表因存储地址故所需8字节。对于大量数据,链表比数组所需的内存要小,原因是数组要预留很多空的内存空间。

(2)C语言中表述

(1)逻辑代码——插入第1个节点
typedef struct Node {
    int data;        // 用于存储数据
    struct Node* link;   // 指向下一个节点的指针,仅仅是指针,不包含数据
} Node;


//(1) 创建指针
Node* A;  //声明指向节点的指针 A
A = NULL; //最初列表为空,指针 A 不指向任何位置


//(2) 插入节点。用malloc函数创建内存块,参数是内存块所需字节数
Node* temp = (Node*)malloc(sizeof(Node));
//说明:malloc返回void指针,该指针为我们提供分配的内存块地址
//说明:我们把它保存在名为temp的变量里,最后需要类型转换(由于返回void指针)


//(4) 把数据写入该节点,并调整链接。

#if 0
(*temp).data = 2;
//说明:向 A 写入地址,以及调整新创建节点的链接字段。为此必须解引用指针(也就是刚创建的变量temp)。
//说明:变量前加"*"可解引用并可以修改地址的值(也就是内容)。
(*temp).link = NULL;
//说明:我们这个临时变量temp指向这个节点,此时这个节点是第一个也是最后一个节点,所以链接不是是NULL

#else
temp->data = 2;
temp->link = NULL;
#endif

A = temp;
//说明:把新创建节点的地址写入 A 
//说明:temp事实用来暂时存储节点地址,一旦链接调整完成,temp就可用于其他目的
//A和temp都是指针,都是指向malloc分配的这个内存地址,只是temp是临时变量。
    
(2)逻辑代码——遍历后再链表最后插入第1个节点
typedef struct Node {
    int data;       
    struct Node* link;  
} Node;

//(1) 创建指针
Node* A;  
A = NULL; 

//(2) 构建第1个节点,并写入数据和地址
Node* temp = (Node*)malloc(sizeof(Node));
temp->data = 2;
temp->link = NULL;

//(3)把新节点的地址写入原本为NULL的此前尾节点的link
A = temp;

//(4)遍历节点地址后,插入新节点
Node* temp1 = A;
while(temp1->link != NULL){ //用最后一个节点地址为空,作为判断
     temp1 = temp1->link;
}

//(5)创建新节点,并在新节点内写入数据
Node* newtemp = (Node*)malloc(sizeof(Node));
newtemp->link = NULL;
newtemp->data = 3;

//(6)把新节点的地址写入原本为NULL的此前尾节点的link
temp1->link = newtemp;
(3)逻辑代码——从头部开始插节点
#include <stdio.h>
#include <stdlib.h>

typedef struct Node{
        int data;
        struct Node* next;
}Node;

struct Node* head;  //声明Node*类型的一个结构体指针为head

void Insert(int x){
        Node* temp = (Node*)malloc(sizeof(Node)); //分配一个新内存,并把地址赋给temp
        temp->data = x; //解指针后改写在结构内data

        //以下两行的数据不能错,一定是先连接后面的节点,然后才是前面的节点
        temp->next = head; //就是把原本头节点的地址先写入解指针*temp的next里
        head = temp; //把新的头节点地址赋值给head(这条把2种可能性都考虑:1. head != NULL,2. head ==NULL)
}

void Print(){
        Node* temp = head;
        printf("List is: ");
        while(temp != NULL){
                printf(" %d", temp->data);  //遍历地址
                temp = temp->next;          //输出数据
        }
        printf("\n");
}

int main(){
        head = NULL;
        printf("How many number?\n");
        int n, i, x;
        scanf("%d", &n);
        for(i = 0; i < n; i++){
                printf("Enter the number");
                scanf("%d", &x);
                Insert(x);
                Print();
        }
}

(4)逻辑代码——从任意位置插入节点(旧地址先传递,新地址后连接)
#include <stdio.h>
#include <stdlib.h>


typedef struct Node{
        int data;
        struct Node* next;
}Node;
struct Node* head;

void Insert(int data, int n){
        Node* temp1 = (Node*)malloc(sizeof(struct Node));
        temp1->data = data;
        temp1->next = NULL;
        if(n == 1){
                temp1->next = head;
                head = temp1;
                return;
        }

        Node* temp2 = head;
        for(int i = 0; i< n-2;i++){
                temp2 = temp2->next;
        }
        temp1->next = temp2->next;
        temp2->next = temp1;
}
void Print(){
        Node* temp = head;
        while(temp != NULL){
                printf("%d ", temp->data);
                temp = temp->next;
        }
        printf("\n");
}



int main(){
        head = NULL;
        Insert(2,1); //List: 2
        Insert(3,2); //List: 2,3
        Insert(4,1); //List: 4,2,3
        Insert(5,2); //List: 4,5,2,3
        Print();
}

(3)备注:

(1)int *p = &a的含义就是 p存储了 &a,然后p的类型是 int*

(2)每次函数执行完成时,所有局部变量都会从栈内存释放。

(5)逻辑代码——从任意位置删除节点(到n-2跳到n)
#include <stdio.h>
#include <stdlib.h>


typedef struct Node{
                int data;
                                struct Node* next;
}Node;
struct Node* head; //global

void Insert(int data)
{
        Node* temp = (Node*)malloc(sizeof(Node)); //分配一个新内存,并把地址赋给temp
        temp->data = data; //解指针后改写在结构内data

        //以下两行的数据不能错,一定是先连接后面的节点,然后才是前面的节点
        temp->next = head; //就是把原本头节点的地址先写入解指针*temp的next里
        head = temp; //把新的头节点地址赋值给head(这条把2种可能性都考虑:1. head != NULL,2. head ==NULL)
}

void Print(){
        Node* temp = head;
        printf("List is: ");
        while(temp != NULL){
                printf(" %d", temp->data);  //遍历地址
                temp = temp->next;          //输出数据
        }
        printf("\n");


}

void Delete(int n)//Delete node at position n
{
        struct Node* temp1 = head;

        if(n == 1){
                head = temp1->next;
                free(temp1);
                return; //防止进行下面的
        }

        int i;
        for (i = 0; i< n-2; i++){
                temp1 = temp1->next;
        }
        struct Node* temp2 = temp1->next;
        temp1->next = temp2->next;
        free(temp2);
}

int main(){
        head = NULL;
  Insert(2);
  Insert(4);
  Insert(6);
  Insert(5);//List: 2,4,6,5
  Print();
        int n;
        printf("Enter a position");
        scanf("%d", &n);
        Delete(n);
        Print();
}

(6)逻辑代码——逆转链表

截图参考来自,很好的视频

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

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

相关文章

C# 之某度协议登录,JS逆向,手机号绑定,获取CK

.NET兼职社区 .NET兼职社区 .NET兼职社区 .NET兼职社区 有需要指导&#xff0c;请私信我留言V或者去社区找客服。

SpringcloudAlibaba黑马笔记(部分)

第一章 微服务介绍 1.1 系统架构演变 随着互联网的发展&#xff0c;网站应用的规模也在不断的扩大&#xff0c;进而导致系统架构也在不断的进行变化。 从互联网早起到现在&#xff0c;系统架构大体经历了下面几个过程 : 单体应用架构 ---> 垂直应用架构 ---> 分布 …

Redis 基础篇

一、redis 概念及特性 1.1 Redis 概念 Redis&#xff08;Remote Dictionary Server&#xff09;&#xff0c;即远程字典服务&#xff0c;是一个开源的高性能键值存储数据库&#xff0c;可以用作数据库、缓存和消息中间件。 redis 官网&#xff1a;Redis - The Real-time Data P…

DAY15 神经网络的参数和变量

DAY15 神经网络的参数和变量 一、参数和变量 在神经网络中&#xff0c;参数和变量是两个关键概念&#xff0c;它们分别指代不同类型的数据和设置。 参数&#xff08;Parameters&#xff09; 定义&#xff1a;参数是指在训练过程中学习到的模型内部变量&#xff0c;这些变量…

[离线数仓] 总结二、Hive数仓分层开发

接 [离线数仓] 总结一、数据采集 5.8 数仓开发之ODS层 ODS层的设计要点如下: (1)ODS层的表结构设计依托于从业务系统同步过来的数据结构。 (2)ODS层要保存全部历史数据,故其压缩格式应选择压缩比率,较高的,此处选择gzip。 CompressedStorage - Apache Hive - Apac…

Chromium源码windows下载和编译

官方地址&#xff1a;chromium/docs/windows_build_instructions.md at main chromium/chromium GitHub Chromium介绍 Chromium 是一个开源浏览器项目&#xff0c;旨在为所有用户构建更安全、更快、更稳定的网络体验方式。掌握Chromium的编译和开发是浏览器项目相关的开发者…

maven如何从外部导包

1.找到你项目的文件位置&#xff0c;将外部要导入的包复制粘贴进你当前要导入的项目下。 2.从你的项目目录下选中要导入的包的pom文件即可导包成功 注意一定是选中对应的pom文件 导入成功之后对应的pom.xml文件就会被点亮

力扣 跳跃游戏

每次更新目标位置时&#xff0c;实际上是在做一个局部的最优选择&#xff0c;选择跳跃能够到达当前目标位置的最远位置。因为每次更新目标位置时&#xff0c;都是基于当前能跳跃到的最远位置&#xff0c;因此最终的结果是全局最优的。 题目 从前往后遍历&#xff0c;更新可以到…

第二十八周学习周报

目录 摘要Abstract1 GFPGAN1.1 总体结构1.2 实验研究1.3 代码分析 总结 摘要 本周主要的学习内容是GFPGAN模型。GFPGAN是一种基于生成对抗网络(GAN)的模型&#xff0c;其利用封装在预训练的人脸GAN中的丰富多样的先验进行人脸图像的修复。这种生成面部先验&#xff08;GFP&…

成为LabVIEW自由开发者

成为LabVIEW自由开发者的体验可以非常丰富且具有挑战性&#xff0c;同时也充满了自我成长和多样化项目的机会。 ​ 1. 高度的灵活性与自由度 工作时间与地点&#xff1a;作为自由开发者&#xff0c;你可以自由选择工作时间和地点。你可以在家工作&#xff0c;也可以选择在咖啡…

Electron快速入门——跨平台桌面端应用开发框架

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

SpringBoot之核心配置

学习目标&#xff1a; 1.熟悉Spring Boot全局配置文件的使用 2.掌握Spring Boot配置文件属性值注入 3.熟悉Spring Boot自定义配置 4.掌握Profile多环境配置 5.了解随机值设置以及参数间引用 1.全局配置文件 Spring Boot使用 application.properties 或者application.yaml 的文…

openai swarm agent框架源码详解及应用案例实战

文章目录 简介数据类型Agent类Response类Result类Swarm类run_demo_loop交互式会话 基础应用agent-handsofffunction-callingcontext_variablestriage_agent 高阶应用通用客服机器人(support bot)构建航班服务agent 参考资料 openai 在24年10月份开源了一个教育性质的多agents协…

JVM vs JDK vs JRE

JVM是Java虚拟机的缩写&#xff0c; 用于实现Java的一次编译&#xff0c;处处运行。 Java代码写成.class后&#xff0c;由本地的虚拟机运行。 JDK&#xff08;Java Development Kit&#xff09;是一个功能齐全的 Java 开发工具包&#xff0c;供开发者使用。 JDK包含了JRE。…

【网页自动化】篡改猴入门教程

安装篡改猴 打开浏览器扩展商店&#xff08;Edge、Chrome、Firefox 等&#xff09;。搜索 Tampermonkey 并安装。 如图安装后&#xff0c;浏览器右上角会显示一个带有猴子图标的按钮。 创建用户脚本 已进入篡改猴管理面板点击创建 脚本注释说明 name&#xff1a;脚本名称。…

微信小程序用的SSL证书有什么要求吗?

微信小程序主要建立在手机端使用&#xff0c;然而手机又涉及到各种系统及版本&#xff0c;所以对SSL证书也有要求&#xff0c;如果要小程序可以安全有效的访问需要满足以下要求&#xff1a; 1、原厂SSL证书&#xff08;原厂封&#xff09;。 2、DV单域名或者DV通配符。 3、兼…

【电子通识】PWM驱动让有刷直流电机恒流工作

电机的典型驱动方法包括电压驱动、电流驱动以及PWM驱动。本文将介绍采用PWM驱动方式的恒流工作。 首先介绍的是什么是PWM驱动的电机恒流工作&#xff0c;其次是PWM驱动电机恒流工作时电路的工作原理。 PWM驱动 当以恒定的电流驱动电机时&#xff0c;电机会怎样工作呢&#xff1…

Unity学习之UGUI进阶

一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 &#xff08;1&#xff09;常用事件接口 &#xff08;2&#xff09;不常用事件接口 3、使用事件监听接口 &#…

电脑硬盘系统迁移及问题处理

一、系统迁移准备 1、确认你的电脑主板是否支持安装两块硬盘,如电脑主板有多个M2硬盘接口,我们将新硬盘安装到主板上,原来的老硬盘安装在第二个接口上,主板只有一个M2接口的话可以使用移动硬盘盒。 2、新硬盘安装好后,我们进入原来的系统,在 此电脑–右键–管理–磁盘管…

【NLP高频面题 - Transformer篇】Transformer的输入中为什么要添加位置编码?

Transformer的输入中为什么要添加位置编码&#xff1f; 重要性&#xff1a;★★★ Transformer 将句子中的所有词并行地输入到神经网络中。并行输入有助于缩短训练时间&#xff0c;同时有利于学习长期依赖。不过&#xff0c;并行地将词送入 Transformer&#xff0c;却不保留词…