数据结构day02(链表)

news2024/11/24 10:43:42

【1】链表 Link list

链表又称单链表/链式存储结构,用于存储逻辑关系为“一对一”的数据

和顺序表不同,使用链表存储数据,不强制要求在内存中集中存储,各个元素可以分散存储在内存中。

所以在链表中,每个数据元素可以配有一个指针用于找到下一个元素即节点,这意味着,链表上的每个“元素”都如下图

 

 链表的特性

逻辑结构:线性结构

存储结构:链式存储

特点:内存不连续,需要通过指针链接,大小不固定,解决顺序表插入删除麻烦的问题

操作:增删查改

struct node
{
int data;                      //数据域,用于存储数据
struct node * next;            //指针域,用于存储下一个节点的地址
};

单项链表

有头链表:存在一个头结点,头节点的数据域无效,指针域有效

无头链表:每一个节点的数据域和指针域都有效

 遍历无头单向链表

 

#include <stdio.h>
#include <stdlib.h>
typedef char datatype; // 重定义字符类型
typedef struct node
{
    datatype data;     // 数据用来存数据
    struct node *next; // 指针域用来存下一个节点的地址
} Node_t, *Node_p;     // 重定义结构体数据类型,和结构体指针类型

/*遍历无头单项链表*/
 int main(int argc, char const *argv[])
 {
     //定义4个节点并赋值
     Node_t A = {'a',NULL};
     Node_t B = {'b',NULL};
     Node_t C = {'c',NULL};
     Node_t D = {'d',NULL};

     //连接4个节点
     A.next = &B;
     B.next = &C;
     C.next = &D;

     //定义一个头指针指向第一个节点
     Node_p p = &A;

     //通过指针遍历无头单项链表
     while(p != NULL)
     {
         printf("%c ",p->data);//打印每个节点数据域中的值
         p = p->next;//让p指向下一个节点
     }
     printf("\n");
     return 0;
 }

遍历有头单向链表

 

#include <stdio.h>
#include <stdlib.h>
typedef char datatype; // 重定义字符类型
typedef struct node
{
    datatype data;     // 数据用来存数据
    struct node *next; // 指针域用来存下一个节点的地址
} Node_t, *Node_p;     // 重定义结构体数据类型,和结构体指针类型
/*遍历有头单项链表*/
 int main(int argc, char const *argv[])
 {
     // 定义4个节点并附值
     Node_t A = {'a', NULL};
     Node_t B = {'b', NULL};
     Node_t C = {'c', NULL};
     Node_t D = {'d', NULL};

     // 连接4个节点
     A.next = &B;
    B.next = &C;
    C.next = &D;

     // 定义头节点,数据域无效,指针域有效
     Node_t H = {'\0', &A};

     // 定义一个头指针,指向头节点
     Node_p p = &H;
 #if 0 //条件编译
     p = p->next; // 先跨越头节点,指向第一个数据域有效的节点A
     while (p != NULL) //当前指针不是空
     {
         printf("%c ", p->data);//打印数据域内容
         p = p->next;//指向下一个节点
     }
     printf("\n");
 #else
     while (p->next != NULL)//当前指针的指针域内数据是否为空
     {
         p = p->next;
         printf("%c ",p->data);
     }
     printf("\n");
 #endif
         return 0;
 }

 

 链表尾插法

写一个有头单向链表,用于保存输入的学生成绩,实现一输入学生成绩就创建一个新的节点,将成绩保存起来。再将该节点链接到链表的尾,直到输入-1结束。

要求:每个链表的节点由动态内存分配得到 , 也就是用malloc。

过程:

  1. malloc申请空间link_node_t大小作为头节点
  2. 将新节点放到链表尾部

 

 

#include <stdio.h>
#include <stdlib.h>
typedef char datatype; // 重定义字符类型
typedef struct node
{
    datatype data;     // 数据用来存数据
    struct node *next; // 指针域用来存下一个节点的地址
} Node_t, *Node_p;     // 重定义结构体数据类型,和结构体指针类型
/*链表尾插法*/
 int main(int argc, char const *argv[])
 {
     Node_p p_new = NULL;  // 先定义一个结构体指针,置空待用
     Node_p p_tail = NULL; // 先定义一个结构体指针,置空待用
     int score = -1;            // 定义一个变量存放成绩

     // 创建一个头节点,用头指针p指向头节点
     Node_p H = (Node_p)malloc(sizeof(Node_t));//malloc开辟堆区空间
     if (NULL == H)//判断堆区空间是否开辟成功
     {
         printf("malloc lost");
     }
     H->next = NULL;//头节点指针域置空
     p_tail = H;//让尾指针指向头节点

     //循环输入学生成绩直到-1结束,创建新节点存放学生成绩,尾插的链表中
     while(1)//循环输入成绩
     {
         scanf("%d",&score);
         if(score == -1)//结束条件
         {
         break;
         }
         p_new = (Node_p)malloc(sizeof(Node_t));//创建新节点,用来存放学生成绩
         if(NULL == p_new)//判断堆区空间是否开辟成功
         {
            printf("malloc error");
         }
         //初始化新节点,把成绩赋值到数据域,指针域置空
         p_new->data = score;
         p_new->next = NULL;
         p_tail->next = p_new;//将新节点连接到当前尾节点,作为新的尾节点,就是把新节点的地址存放到当前尾节点的指针域中
         p_tail = p_new;//将当前尾节点移动到新节点上,是新节点成为尾节点,尾指针永远指向最后一个节点
     }
     //遍历链表
     while(H->next != NULL)
     {
         H = H->next;
         printf("%d ",H->data);
     }
     printf("\n");
     return 0;
 }

 有头单向链表的函数操作

 


#include <stdio.h>
#include <stdlib.h>
typedef char datatype; // 重定义字符类型
typedef struct node
{
    datatype data;     // 数据用来存数据
    struct node *next; // 指针域用来存下一个节点的地址
} Node_t, *Node_p;     // 重定义结构体数据类型,和结构体指针类型/*有头单向链表的函数操作*/
/*创建一个空的单向链表*/
Node_p Create()
{
    Node_p p = (Node_p)malloc(sizeof(Node_t)); // 开辟一个节点大小的堆区空间
    if (NULL == p)                             // 开辟失败
    {
        printf("malloc lost");
        return NULL;
    }
    p->next = NULL; // 初始化头节点指针域
    return p;       // 开辟成功,返回
}

/*计算链表的长度*/
int length(Node_p p)
{
    int len = 0;            // 定义一个变量来表示长度,并赋初始值为0
    while (p->next != NULL) // 当指针域不等于NULL就说明没到最后一个节点
    {
        p = p->next; // 指针向下一个节点移动
        len++;       // 长度加加
    }
    return len; // 返回长度值
}

/*向项链表中插入数据*/
void Insert(Node_p p, int post, int data)
// p 保存链表的头指针   post 要插入的位置   data  要插入的数据
{
    // 容错判断
    if (post < 0 || post > length(p)) // 插入位置小于0或大于链表长度
    {
        printf("post error");
    }
    Node_p p_new = NULL;           // 创建一个指针,置空备用,用来存放要插入的新数据
    for (int i = 0; i < post; i++) // for循环遍历到要查如位置前的那该个节点
        p = p->next;
    p_new = (Node_p)malloc(sizeof(Node_t)); // 开辟一个节点大小堆区空间存放新数据
    if (NULL == p_new)
    {
        printf("malloc lost");
    }
    p_new->data = data; // 在数据域存放要查入的数据
    p_new->next = NULL; // 初始化为NULL;
    // 链接新节点时,要先连后面,再连前面(否则,先连前面后面的地址就找不到了)
    p_new->next = p->next; // 让新节点链接到要插入的位置节点上
    p->next = p_new;       // 让要插入位置前的那个节点连接到新的节点上
}

/*修改链表的内容*/
void Modify(Node_p p, int post, int data)
// p 保存链表的头指针  post  要修改的数据位置  data   要修改成的数据
{
    // 容错判断
    if (post < 0 || post > length(p))
    {
        printf("error\n");
    }
    for (int i = 0; i < post; i++) // for循环遍历到要插入位置前的那该个节点
        p = p->next;
    Node_p mod = p->next; // 定义一个指针指向要插入位置的节点
    mod->data = data;     // 修改要修改的值
}

/*删除链表的内容*/
void Delete(Node_p p, int post)
// p 保存链表的头指针  post  要删除的数据位置
{
    // 容错判断
    if (post < 0 || post > length(p))
    {
        printf("delete error\n");
    }
    for (int i = 0; i < post; i++)
        p = p->next;
    Node_p p_del; // 定义一个指针指向要删除的节点
    p_del = p->next;
    p->next = p_del->next; // 让被删除的节点前的那个节点链接到被删除的那个节点后的节点
    free(p_del);           // 释放被删除的那个节点
    p_del = NULL;          // 将指向被删除的那个节点的指针置空
}

/*查找链表中的内容*/
int Serarch(Node_p p, int post)
// p 保存链表的头指针  post  要查询的数据位置
{
    // 容错判断
    if (post < 0 || post > length(p))
    {
        printf("error\n");
        return -1;
    }
    for (int i = 0; i < post; i++)
        p = p->next;
    Node_p ser = p->next; // 定义一个指针指向要查询的节点
    return ser->data;     // 返回查询的节点数据域中的内容
}
/*遍历链表*/
void show(Node_p p)
// p 保存链表的头指针
{
    while (p->next != NULL)
    {
        p = p->next;
        printf("%d ", p->data);  
    }
    printf("\n");
}

int main(int argc, char const *argv[])
{
    Node_p H = Create();
    for (int i = 0; i < 5; i++) // 循环调用插入函数
        Insert(H, i, i);
    printf("插入后:\n");
    show(H);
    // Insert(H, -1, 6);
    Delete(H, 4);
    printf("删除后:\n");
    show(H);
    Modify(H, 1, 100);
    printf("修改后:\n");
    show(H);
    int data = Serarch(H, 1);
    printf("查询的数据:\n");
    printf("%d\n", data);
    return 0;
}

 

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

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

相关文章

K7系列FPGA多重启动(Multiboot)

Xilinx 家的 FPGA 支持多重启动功能&#xff08;Multiboot&#xff09;&#xff0c;即可以从多个 bin 文件中进行选择性加载&#xff0c;从而实现对系统的动态更新&#xff0c;或系统功能的动态调整。 这一过程可以通过嵌入在 bit 文件里的 IPROG 命令实现上电后的自动加载。而…

计算机网络体系结构【★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、计算机网络概述 1. 计算机网络的性能指标&#xff08;★★&#xff09; 1&#xff09;速率&#xff08;speed&#xff09; 指连接到计算机网络上的节点在数…

用爬虫玩转石墨文档详细操作步骤

石墨文档是一款强大的在线文档编辑和协作工具&#xff0c;它支持文字处理、表格制作、演示文稿等多种功能&#xff0c;适用于个人和团队的办公需求。以下是一些玩转石墨文档的详细步骤和技巧&#xff1a; 1. 注册和登录 注册&#xff1a;访问石墨文档官网&#xff0c;点击“注…

【漏洞复现】某骋BPM系统——Handler.ashx——sql注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 某骋BPM系统是一款功能全面的商业流程管理平台,旨在帮助企业实现…

车辆横向控制的参考路径估计

Reference Path Estimation for Lateral Vehicle Control 车辆横向控制的参考路径估计 Abstract Autonomous driving cars have been a hot topic in the media in recent years, with more and more tech companies and universities presenting projects with fully autom…

同态加密和SEAL库的介绍(九)CKKS 参数心得 1

写在前面&#xff1a; 前面几篇有官方的说明和示例做支撑&#xff0c;相信能给大家比较多的参考价值。但是由于没能对同态加密有更深入的了解&#xff0c;所以在我具体使用的时候出现各种问题。本篇是针对这些问题做的一些测试&#xff0c;由结论产生的了些个人的推测&#xff…

准大学生电脑应该怎么选?

随着夏日的尾声悄然临近&#xff0c;各位准大学生们是不是已经迫不及待想要翻开大学生活的崭新篇章了呢&#xff1f;作为准大学生&#xff0c;选择一台称心如意的电脑绝对是大家最近最头疼的事情&#xff0c;那我们应该怎么选择适合自己的电脑呢&#xff1f; 01 处理器&#x…

井字棋游戏(HTML+CSS+JavaScript)

&#x1f30f;个人博客主页&#xff1a;心.c 前言&#xff1a;这两天在写植物大战僵尸&#xff0c;写不动了&#xff0c;现在和大家分享一下之前我写的一个很简单的小游戏井字棋&#xff0c;这个没有AI&#xff0c;可以两个人一起玩&#xff0c;如果大家觉得我哪里写的有一些问…

【Redis】Linux CentOS Redis 的安装—(一)

Redis 一、获取源二、解压编译 一、获取源 //redis-stable是最新稳定版 wget https://download.redis.io/redis-stable.tar.gz二、解压编译 //我指定目录/app tar -xzvf redis-stable.tar.gz -C /appcd /app/redis-stablemake && make install##三 、修改配置启动 …

重复的子字符串 | LeetCode-459 | 字符串匹配 | KMP | 双指针

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f579;️KMP练习题 &#x1f4cc;LeetCode链接&#xff1a;459. 重复的子字符串 文章目录 1.题目描述&#x1f34d;2.题解&#x1fad0;2.1 暴力解法&#x1…

enhanced Input Action IA_Look中Action value引脚没有分割结构体引脚的选项

UE5系列文章目录 文章目录 UE5系列文章目录前言二、使用步骤解决办法 前言 据说&#xff0c;unreal engine5中准备废弃“项目设置”中“输入”&#xff0c;操作映射&#xff0c;轴映射。取而代之的是&#xff1a; 使用增强的输入动作&#xff08;Enhanced Input Actions&#…

【QT】Qt SDK的下载,安装和环境配置

目录 一&#xff0c;Qt SDK的下载二&#xff0c;Qt SDK的安装三&#xff0c;验证Qt SDK安装是否成功四&#xff0c;Qt环境变量配置 一&#xff0c;Qt SDK的下载 进入下面两个网站都可以进行下载&#xff1a; Qt 下载官⽹ 国内清华源 进⼊官⽹&#xff0c;按如下图⽰进⾏相应…

Allegro如何导入DXF结构文件并生成板框(1)?

在用Allegro进行PCB设计时,需要导入DXF结构文件,由此来生成PCB的板框。 本节先讲Allegro如何导入DXF结构文件?下节讲如何利用导入的DXF结构文件生成OUTLINE板框。 Allegro如何导入DXF结构文件并生成板框(2)?-CSDN博客 详细操作方法如下: 1、选择菜单栏File 选择Import…

【EI会议】第三届环境工程与可持续能源国际会议征稿开启

第三届环境工程与可持续能源国际会议&#xff08;EESE 2024&#xff09;将于2024年12月20日至21日在湖南长沙召开&#xff0c;诚挚邀请相关领域学者、专家加入会议&#xff0c;开展学术讨论和研究&#xff0c;共同助推环境工程与可持续能源产学研领域的进步&#xff01; 征稿主…

SDK does not contain ‘libarclite‘ at the path

Xcode15运行报错:SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/ Developer/Toolchains/XcodeDefault.xctoolchain/us/lib/arc/libarclite_iphoneos.a 如下图: 阅读报错信息,它的意思是 SDK没有包含 libarclite 这个文件,这个文件的路径是: …

基于 face_recognition 的人脸识别的小工具

使用 face_recognition 和 pyside2&#xff0c;开发了一个小工具&#xff0c;识别指定的人脸照片&#xff0c;保存到指定的文件夹。 源码如下&#xff1a; import sys import os import shutil import face_recognition import logging from PySide2.QtWidgets import QApplic…

PDF文件转换为HTML文件

推荐使用 pdf2htmlEX&#xff08;因为确实做的比较全&#xff09; pdf2htmlEX 是一个开源工具&#xff0c;可以将PDF文件转换为HTML文件。你需要先安装pdf2htmlEX工具&#xff0c;并确保它在你的系统路径中可用。&#xff08;花时间最多就是找包&#xff09; 安装 pdf2htmlEX …

API以及添加学生信息练习

API:应用程序编程接口 简单理解&#xff1a;API就是别人已经写好的东西&#xff0c;我们不需要自己编写&#xff0c;直接使用即可 Java API&#xff1a;指的就是jdk中提供的各种功能的Java类&#xff0c;这些类将底层的实现封装起来&#xff0c;我们不需关心这些类是如何实现的…

什么是神中神公司?发表内卷言论,分分钟要你道歉...

谷歌 海的那边&#xff0c;这几天最乐的新闻&#xff0c;是谷歌前 CEO 批评员工不拼命工作后道歉。 今年 4 月&#xff0c;谷歌前 CEO 埃里克施密特&#xff08;Eric Schmidt&#xff09;在斯坦福大学的一次演讲中&#xff0c;被问及 OpenAI 和 Anthropic 等初创公司目前在人工…

【全面解析】芯片采购渠道策略:原厂直采VS代理VS现货市场

芯片作为现代科技的基石&#xff0c;其重要性不言而喻。无论是智能手机、汽车电子、物联网设备还是高性能计算领域&#xff0c;都离不开芯片的支持。随着5G、AI、大数据等前沿技术的飞速发展&#xff0c;对芯片的需求量持续攀升&#xff0c;如何确保稳定、高效的芯片供应链成为…