Day27-【13003】短文,单链表应用代码举例

文章目录

    • 单链表的应用概览
      • 查找单链表倒数第k个结点
      • 查找单链表的中间结点
      • 将单链表逆置
    • 第二章真题检测

单链表的应用概览

在这里插入图片描述

查找单链表倒数第k个结点

本节给出单链表的4个应用示例。单链表结点的定义与本章第三节中的定义相同。为了方便,重新写出来。

#define TRUE 1
#define FALSE 0
#define ERROR -1

单链表中每个元素的类型是ELEMType,单链表中结点及链表的定义如下。

typedef int ELEMTYPE;
typedef struct node {  //单链表结点
    ELEMTYPE data;     //数据域
    struct node *next; //指针域
} LinkNode;
typedef LinkNode *LinkList;  //单链表
typedef int Position;        //位置

为了展示单链表的应用,需要先创建一个单链表。

单链表中各元素的值从键盘读入。

定义单链表的头指针LinkListhead=NULL,然后调用本章第三节中的initList(&head)进行初始化。

接下来,调用createMyList(&head)创建单链表。

在createMyList中,先从键盘上输入元素个数,然后依次读入相应个数的整数值,使用这些值构造一个带头结点的单链表。

相应的实现如下。

int createMyList(LinkList * head) {
    // 构造一个带头结点的单链表
    int i, counter, k;
    printf("请输入单链表元素个数: ");
    scanf("%d", &counter);
    if (counter > 0) {
        printf("请输入构成链表的%d个整数: ", counter);
        for (i = 0; i < counter; i++) {
            scanf("%d", &k);
            if (insertList(head, i, k) == FALSE) return FALSE;
        }
    }
    display(head);
    return TRUE;
}

在程序运行后,从键盘输入的单链表元素个数保存在变量counter中。

只有当counter大于0时,才依次读入单链表各元素的值。

读入的值使用本章第三节实现的insertList()函数插入到单链表的表尾。

也可以将待输入的数据预先保存在一个一维数组中,假设数组是a,数组元素个数是na,

则在完成初始化后,调用createMyListFromArray(head,a,na)来构建单链表。

createMyListFromArray的实现如下。

int createMyListFromArray(LinkList * head, int * a, int n) {
    // 读取数组中元素的值,构造一个带头结点的单链表
    int i;
    if (n > 0) {
        for (i = 0; i < n; i++) {
            if (insertList(head, i, a[i]) == FALSE) return FALSE;
        }
    }
    return TRUE;
}

我们已经知道,在单链表中,每个结点含有的指针只有— 个,它指向当前结点的后继结点。

当要访问单链表中正数第K个结点时,从头指针开始,沿指针的方向依次后移k-1次,就可以定位到要访间的结点。

为了统一 ,如果单链表中有头结点,则将头结点也一 起编号。

如果要查找单链表中倒数第k (k≥1) 个结点,则没有这么简单。因为不能从表尾向表头进行遍历,所以不能直接从表尾向表头直接数K个结点。

至少有两个办法可以实现这个操作。

如果知道单链表的长度,那么查找倒数第K个结点就很容易了。

假设单链表中含有n个结点,则倒数第K个结点即第n-k+l个结点。

如果单链表头结点的数据域中保存了单链表的长度,则可以很方便地找到这个值。

如果没有保存,则需要遍历一 遍单链表,并对结点个数进行计数,从而得到单链表的长度。

当不知道单链表的长度时,还可以使用下面介绍的方法来查找单链表倒数第k个结点。

使用两个指针front和rear , 均从表头开始向表尾方向移动。

初始时,先令front前进K步,当个 “排头兵'。

这样front和rear指向的位置相距k个结点。

然后两个指针同步前进。

当front到达表尾时,rear即指向倒数第k个结点。

在这个过程中,可能会出现几种例外情况,需要加以特殊处理。

一种例外是,给定的单链表是空表。

对于空表,不能进行相应的查找。所以程序需要判定给定的单链表是不是空表。

另一种例外是,给定的k值不合理。

程序中需要判定k值是不是不大于表长的一个正整数。

程序的实现如下。

LinkNode * findKth(LinkList * head, int k) {
    // 查找倒数第k个结点
    LinkNode * front, * rear;
    int i, flag = 1;
    if (k <= 0) {
        printf("k必须大于零!");
        return NULL;
    }
    if (*head == NULL) {
        printf("链表错误\n");
        return NULL;
    }
    front = *head;
    rear = *head;
    for (i = 0; i < k; i++) {
        if (front!= NULL) front = front->next;
        else {
            flag = 0;
            break;
        }
    }
    if (!flag) {
        printf("k值大于表长!");
        return NULL;
    }
    while (front!= NULL) {
        front = front->next;
        rear = rear->next;
    }
    return rear;
}

查找单链表的中间结点

单链表的长度是任意的,所以中间结点并不能确定是其中的第几个结点,具体的值要依单链表的长度而定。

而且,当单链表结点个数是偶数时,会有两个中间结点,这里只求前一个结点。

不能简单地调用上面给出的findKth函数,但实现思想是类似的。

仍然使用两个指针,并从表头开始同步地向表尾方向移动,一个指针每次走两步,另一个指针每次走一步。

  • 这个之前学习过

这样,当“排头兵”指针到达表尾时,后面的指针即指向链表的中间结点。

与findKth函数中一样,两个指针分别是front和rear。

程序的实现如下。

LinkNode * findMiddle(LinkList * head) {
    // 查找中间结点, 返回指向中间结点的指针
    LinkNode * front, * rear;
    if (*head == NULL) {
        printf("链表错误\n");
        return NULL;
    }
    front = *head;
    rear = *head;
    while (front!= NULL) {
        // 当前指针front没有移动到最后一个结点之前, 继续循环
        front = front->next;
        if (front!= NULL) {
            front = front->next;
            rear = rear->next;
        }
        else {
            break;
        }
    }
    return rear;
}

将单链表逆置

假设单链表中含有头结点。

原单链表的头结点保留,仍为逆置后新单链表的头结点。

所以,对于头指针head,先不进行处理。

从第一个数据结点开始,依次让每个结点的指针域反向,由指向其后继结点转为指向其前驱结点。

为了使处理过程中单链表的链接不中断,使用三个指针分别指向相邻的三个结点,

如图2-24所示。

在这里插入图片描述

第一个数据结点需要特殊处理,因为它将是逆置后单链表的表尾结点,next域必须置为NULL

对于单链表中的其他结点,让middle所指结点的next域指向left所指结点,即left所指结点的原后继(middle所指)变为它的新前驱。

然后,三个指针依次后移一个位置。

当所有结点中的next域都转向后,再将head所指的头结点链接在表头处。

程序的实现如下。

int reverse(LinkList * head) {
    // 将单链表逆置
    LinkNode * left, * middle, * right;
    if (*head == NULL) {
        printf("链表错误\n");
        return FALSE;
    }
    left = (*head)->next;
    if (left!= NULL) middle = left->next;
    left->next = NULL;
    while (middle!= NULL) {
        right = middle->next;
        middle->next = left;
        left = middle;
        middle = right;
    }
    (*head)->next = left;
    return TRUE;
}

第二章真题检测

在这里插入图片描述

1、链表

B、D

2、顺序表

A、E

3、F是两者共有

支持顺序存取,链表和顺序表都支持,这个是最基本的存取嘛

4、C是链表独有

​ 链表所需空间与元素个数成正比

来自AI:

链表中每个元素都存储在一个独立的节点中,每个节点除了存储元素本身的数据外,还需要额外的空间来存储指针(用于指向下一个节点或前一个节点和下一个节点 )。随着元素个数的增加,节点的数量也相应增加,由于每个节点都有数据部分和指针部分,所以整体占用的空间也随之增加,呈现出与元素个数成正比的关系。

若要存储整数 1、2、3,需要创建 3 个节点:

  • 第一个节点存储 1,同时有一个指针指向第二个节点;
  • 第二个节点存储 2,同时有一个指针指向第三个节点;
  • 第三个节点存储 3,由于它是最后一个节点,其指针指向NULL

每增加一个元素,就要新增一个节点,也就增加了存储数据和指针的空间。比如再增加一个元素 4,就需要再创建一个节点来存储 4,并将其与前一个节点通过指针连接起来。所以,元素个数越多,创建的节点就越多,占用的空间也就越大,二者成正比关系。

见,Day27-【13003】短文,什么是单链表、循环链表、双向链表、双向循环链表?它们的操作时间复杂度是多少?如何进行存储单元的计算?,中:单链表所占用的空间量与表中的结点个数成正比。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java求职学习day18

常用的设计原则和设计模式 1 常用的设计原则&#xff08;记住&#xff09; 1.1 软件开发的流程 需求分析文档、概要设计文档、详细设计文档、编码和测试、安装和调试、维护和升级 1.2 常用的设计原则 &#xff08;1&#xff09;开闭原则&#xff08;Open Close Principle…

2025美赛美国大学生数学建模竞赛A题完整思路分析论文(43页)(含模型、可运行代码和运行结果)

2025美国大学生数学建模竞赛A题完整思路分析论文 目录 摘要 一、问题重述 二、 问题分析 三、模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1样例代码&#xff08;仅供参考&#xff09; 4.1.4问题1样例代码运行结果&…

UART ,IIC 和SPI三种总线协议

1.UART 1.1 简介 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;即通用异步收发器。 常见的串行、异步通信总线&#xff0c;两条数据线Tx、Rx&#xff0c;实现全双工通信&#xff0c;常用于主机与外设的通信&#xff0c;点对点。 1.2 硬件连接 交叉…

IPhone14 Pro 设备详情

目录 产品宣传图内部图——后设备详细信息 产品宣传图 内部图——后 设备详细信息 信息收集于HubWeb.cn

海外问卷调查渠道查如何设置:最佳实践+示例

随着经济全球化和一体化进程的加速&#xff0c;企业间的竞争日益加剧&#xff0c;为了获得更大的市场份额&#xff0c;对企业和品牌而言&#xff0c;了解受众群体的的需求、偏好和痛点才是走向成功的关键。而海外问卷调查才是获得受众群体痛点的关键&#xff0c;制作海外问卷调…

如何跨互联网adb连接到远程手机-蓝牙电话集中维护

如何跨互联网adb连接到远程手机-蓝牙电话集中维护 --ADB连接专题 一、前言 随便找一个手机&#xff0c;安装一个App并简单设置一下&#xff0c;就可以跨互联网的ADB连接到这个手机&#xff0c;从而远程操控这个手机做各种操作。你敢相信吗&#xff1f;而这正是本篇想要描述的…

linux——进程树的概念和示例

一些程序进程运行后&#xff0c;会调用其他进程&#xff0c;这样就组成了一个进程树。 比如,在Windows XP的“运行”对话框中输入“cmd”启动命令行控制台&#xff0c;然后在命令行中输入“notepad”启动记事本&#xff0c;那么命令行控制台进程“cmd.exe”和记事本进程“note…

linux系统centos版本上安装mysql5.7

步骤 1: 安装 MySQL 5.7 添加 MySQL Yum Repository 首先&#xff0c;你需要添加 MySQL 的官方 Yum repository。打开终端并执行以下命令&#xff1a; sudo rpm -Uvh https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm 这条命令会为 CentOS 7 添加 MySQL…

Cross-Resolution知识蒸馏论文学习

TPAMI 2024&#xff1a;Pixel Distillation: Cost-Flexible Distillation Across Image Sizes and Heterogeneous Networks 教师模型使用高分辨率输入进行学习&#xff0c;学生模型使用低分辨率输入进行学习 学生蒸馏损失&#xff1a;Lpkd和Lisrd Lpkd&#xff1a;任务损失lo…

java爬虫工具Jsoup学习

目录 前言 一、基本使用 二、爬取豆瓣电影的案例 三、Jsoup能做什么&#xff1f; 四、Jsoup相关概念 五、Jsoup获取文档 六、定位选择元素 七、获取数据 八、具体案例 前言 JSoup是一个用于处理HTML的Java库&#xff0c;它提供了一个非常方便类似于使用DOM&#xff0…

29. 【.NET 8 实战--孢子记账--从单体到微服务】--项目发布

这是本专栏最后一篇文章了&#xff0c;在这片文章里我们不重点讲解如何配置服务器&#xff0c;重点讲如何发布服务&#xff0c;我们开始吧。 一、服务器配置 服务器配置包含&#xff1a;服务器的选择和项目运行环境的配置&#xff0c;下面我们分别来讲解一下。 在服务器选择上…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(五)

Understanding Diffusion Models: A Unified Perspective&#xff08;五&#xff09; 文章概括基于得分的生成模型&#xff08;Score-based Generative Models&#xff09; 文章概括 引用&#xff1a; article{luo2022understanding,title{Understanding diffusion models: A…

TOGAF之架构标准规范-信息系统架构 | 数据架构

TOGAF是工业级的企业架构标准规范&#xff0c;信息系统架构阶段是由数据架构阶段以及应用架构阶段构成&#xff0c;本文主要描述信息系统架构阶段中的数据架构阶段。 如上所示&#xff0c;信息系统架构&#xff08;Information Systems Architectures&#xff09;在TOGAF标准规…

自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测

代码1实现逻辑回归并保存模型 import torch import numpy as np import torch.nn as nn from torch.utils.data import DataLoader, TensorDatasetdata [[-0.5, 7.7], [1.8, 98.5], [0.9, 57.8], [0.4, 39.2], [-1.4, -15.7], [-1.4, -37.3], [-1.8, -49.1], [1.5, 75.6],[0.…

基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真。选择回归法进行最大功率点的追踪&#xff0c;使用光强和温度作为影响因素&#xff0c;电压作为输出进行建模。…

【数据结构】 并查集 + 路径压缩与按秩合并 python

目录 前言模板朴素实现路径压缩按秩合并按树高为秩按节点数为秩 总结 前言 并查集的基本实现通常使用森林来表示不同的集合&#xff0c;每个集合用一棵树表示&#xff0c;树的每个节点有一个指向其父节点的指针。 如果一个节点是它自己的父节点&#xff0c;那么它就是该集合的代…

Flutter android debug 编译报错问题。插件编译报错

下面相关内容 都以 Mac 电脑为例子。 一、问题 起因&#xff1a;&#xff08;更新 Android studio 2024.2.2.13、 Flutter SDK 3.27.2&#xff09; 最近 2025年 1 月 左右&#xff0c;我更新了 Android studio 和 Flutter SDK 再运行就会出现下面的问题。当然 下面的提示只是其…

CSAPP学习:前言

前言 本书简称CS&#xff1a;APP。 背景知识 一些基础的C语言知识 如何阅读 Do-做系统 在真正的系统上解决具体的问题&#xff0c;或是编写和运行程序。 章节 2025-1-27 个人认为如下章节将会对学习408中的操作系统与计算机组成原理提供帮助&#xff0c;于是先凭借记忆将其简单…

动态规划DP 数字三角型模型 方格取数(题目详解+C++代码实现)

方格取数 原题链接 AcWing 1027. 方格取数 题目描述 设有 NN 的方格图&#xff0c;我们在其中的某些方格中填入正整数&#xff0c;而其它的方格中则放入数字0。 如下图所示&#xff1a; 某人从图中的左上角 A 出发&#xff0c;可以向下行走&#xff0c;也可以向右行走&…

【Linux】20.基础IO(2)

文章目录 2. 理解文件系统2.1 inode2.2 如何理解目录2.3 硬链接2.4 软链接2.5 硬链接和软链接的区别 2. 理解文件系统 2.1 inode 我们使用ls -l的时候看到的除了看到文件名&#xff0c;还看到了文件元数据。 ydk_108iZuf68hz06p6s2809gl3i1Z:~/108/lesson20$ ll total 8 drw…