构建有序链表,有序链表的归并,反转链表

本次将对于构建有序链表,有序链表的归并,反转链表,进行一一介绍和代码分享。

首先是一些链表中的基本的函数:

Node* creatList()
{
    Node* headNode = (Node*)malloc(sizeof(Node));
    assert(headNode);
    headNode->next = NULL;
    return headNode;
}

Node* creatNode(Datatype data)
{
    Node* newNode = (Node*)malloc(sizeof(Node));
    assert(newNode);
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

void traverseList(Node* headNode)
{
    Node* posNode = headNode->next;
    while (posNode != NULL)
    {
        printf("%d ", posNode->data);
        posNode = posNode->next;
    }
}

这里很基本,如果理解有困难,请从头学习链表。

以下是构建有序链表,也就是找到符合顺序的位置进行节点插入:

//构建有序链表:和构建顺序表一样,需要找到符合顺序的位置,然后插入元素
//核心是找到第一个比它大的节点,放到这个节点之前(双节点遍历)
void insertData(Node* headNode, Datatype data)
{
    Node* newNode = creatNode(data);
    Node* posNode = headNode->next;
    Node* preNode = headNode;
    //assert(posNode);
    //当前面节点的数据小于data的时候,继续向后走
    while (posNode!= NULL && posNode->data <= data)
    {
        posNode = posNode->next;
        preNode = preNode->next;
    }
    //特殊的情况分析:(短路现象)
    //pos在第一个节点,第一个节点为空,那么说明只有表头,连接表头和newNode
    if (posNode == NULL&&posNode == headNode->next)
    {
        headNode->next= newNode;
    }
    //pos不在第一个节点,但是pos指向空,
    //pos指向最后一个节点的后面一个,也就是还有没有找到大于data的:
    // 说明没有大于data的节点,所以将data与最后连接即可
    else if (posNode == NULL && posNode != headNode->next)
    {
        preNode->next = newNode;
    }
    //找到了位置,插入在pos的前面
    else
    {
        newNode->next = posNode;
        preNode->next = newNode;
    }
}

这个过程和顺序表的构建流程基本相同,比较简单,所以不做过多解释。

接下来是单链表的翻转:

void reverseList(Node* headNode)
{
   //对于1个表头,1个节点;1个表头,2个节点的链表不需要进行翻转
   if (headNode->next == NULL || headNode->next->next == NULL)
   {
       return;
    }
    Node* posNode = headNode->next;
    Node* preNode = NULL;
    Node* sucNode = headNode->next->next;
    while (sucNode != NULL)
    {
        //指向改变
        posNode->next = preNode;
        //整体向后移动
        preNode = posNode;
        posNode = sucNode;
        sucNode = sucNode->next;
    }
    //最后一步改变指向方向
    posNode->next = preNode;
    //将表头与完成反转的第一个节点相连接
    headNode->next = posNode;
}

以下是逐步的过程模拟:结合代码中的注释和过程一一对应更容易理解,其中preNode,sucNode分别是posNode的前驱和后继节点。

示例

假设我们有以下的单链表:

headNode -> 1 -> 2 -> 3 -> 4 -> NULL

我们希望反转后得到:

headNode -> 4 -> 3 -> 2 -> 1 -> NULL

分析执行过程

  1. 初始化指针:
    • posNode 指向第一个元素(1)。
    • preNode 为 NULL(因为没有前驱节点)。
    • sucNode 指向第二个元素(2)。
  2. 进入循环,当 sucNode 不为 NULL 时:
    • 改变 posNode(当前节点)的 next 指针,使其指向前驱节点 preNode
    • 更新 preNode 为当前的 posNode
    • 更新 posNode 为当前的 sucNode
    • 更新 sucNode 为 posNode 的下一个节点。

这个过程会一直持续到 sucNode 为 NULL,即到达链表的末尾。

  1. 在循环结束后,执行以下操作:
    • 将最后一个节点(posNode)的 next 指针指向 preNode
    • 将头节点的 next 指针指向反转后的第一个节点(posNode)。

最后,两个有序链表的归并:

//有序链表的归并:
void mergeList(Node* newHeadNode, Node* head1, Node* head2)
{
    Node* up = head1->next;
    Node* down = head2->next;
    Node* temp = newHeadNode;
    assert(up && down);
    while (up != NULL && down != NULL)
    {
        if (up->data < down->data)
        {
            temp->next= up;
            up = up->next;
        }
        else
        {
            temp->next = down;
            down = down->next;
        }
        temp = temp->next;
    }
    //up结尾,down没结尾
    if (up == NULL && down != NULL)
    {
        temp->next = down;
    }
    //down结尾,up没结尾
    else if (up != NULL && down == NULL)
    {
        temp->next = up;
    }
    //没有两个同时结尾的情况
}

示例和分析执行过程:

假设我们有以下两个有序链表:

head1: 1 -> 3 -> 5
head2: 2 -> 4 -> 6

调用 mergeList(newHeadNode, head1, head2); 后,我们希望得到以下合并后的链表:

newHeadNode -> 1 -> 2 -> 3 -> 4 -> 5 -> 6

执行过程:

  1. up 指向 1down 指向 2temp 指向 newHeadNode
  2. 因为 1 < 2,所以 temp->next = up;,然后 up 移动到 3temp 移动到 1
  3. 现在 up 指向 3down 指向 2
  4. 因为 2 < 3,所以 temp->next = down;,然后 down 移动到 4temp 移动到 2
  5. 重复这个过程,直到 up 或 down 为 NULL
  6. 在本例中,当 up 指向 5 且 down 指向 4 时,因为 4 < 5down 指向的节点会被插入到新链表中。
  7. 当 down 遍历到 NULL 时,up 还有节点 5 和 6。因此,将 up 指向的剩余链表直接连接到新链表的末尾。

对于链表的归并,代码虽然简单,但要理解其中的流程是极为关键的,本次的分享结束,希望对你有帮助。

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

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

相关文章

AJAX (异步的JavaScript 和 XML)

目录 1、什么是AJAX 2、作用 1&#xff09;与服务器通信 2&#xff09;异步交互&#xff08;更新局部页面&#xff09; 3、AJAX 的基本工作原理 4、应用举例 5、jQuery与AJAX 6、使用jQeury实现AJAX 1&#xff09;$.ajax()&#xff1a;发送异步请求 2&#xff09;$.g…

LeetCode-924. 尽量减少恶意软件的传播【深度优先搜索 广度优先搜索 并查集 图 哈希表】

LeetCode-924. 尽量减少恶意软件的传播【深度优先搜索 广度优先搜索 并查集 图 哈希表】 题目描述&#xff1a;解题思路一&#xff1a;解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 给出了一个由 n 个节点组成的网络&#xff0c;用 n n 个邻接矩阵图…

Ubuntu:VSCode中编译运行C++代码

版本&#xff1a;Ubuntu22.04.1 LTS 目录 1 安装VSCode并汉化 2 检查Ubuntu是否已经安装了 GCC 3 在VScode中安装C/C扩展 4 在VSCode中进行C/C配置 1 安装VSCode并汉化 安装VSCode&#xff08;参考之前博客Ubuntu&#xff1a;安装VSCode_ubuntu vscode-CSDN博客&#xff…

面向未来的内容营销:Kompas.ai的趋势预测能力

在这个快速变化的数字时代&#xff0c;内容营销的成功很大程度上取决于能否准确预测并迅速响应未来的趋势。拥有前瞻性的内容策略能够让品牌在竞争中占据优势&#xff0c;与受众建立更深层次的联系。本文将深入探讨预测未来趋势在内容营销战略中的价值&#xff0c;分析Kompas.a…

【LeetCode刷题记录】54. 螺旋矩阵

54 螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 示例 2&#xff1a; 输入&#xf…

基于springboot实现知识管理系统项目【项目源码+论文说明】

基于springboot实现知识管理系统演示 摘要 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#xff0c;针对这个问题开发一个专门适应师生作业交流形式的网站。本文介绍了知识管理系统的开发全过程。通过分析企业对于知识管理系统的需求&#xff0c;创建了…

51单片机学习笔记16 小型直流电机和五线四相电机控制

51单片机学习笔记16 小型直流电机和五线四相电机控制 一、电机分类二、小型直流电机控制1. 简介2. 驱动芯片ULN2003D3. 代码实现dc_motor_utils.cmain.c 三、五线四相步进电机控制1. 步进电机工作原理2. 构造3. 极性区分4. 驱动方式5. 28BYJ-48步进电机&#xff08;1&#xff0…

nextjs渲染篇

1 服务器组件 默认情况下&#xff0c;Next.js 使用服务器组件。 1.1 服务器组件是如何呈现的&#xff1f; 在服务器上&#xff0c;Next.js 使用 React 的 API 来编排渲染。渲染工作被拆分为多个块&#xff1a;按单个路段和Suspense 每个区块分两个步骤呈现&#xff1a; Re…

linux 挂载云盘 NT只能挂载2T,使用parted挂载超过2T云盘

一、删除原来挂载好的云盘和分区 1、查看挂载号的云盘 fdisk -l 发现我们有5千多G但是只挂载了2T&#xff0c;心里非常的慌张&#xff01;十分的不爽&#xff01; 好&#xff0c;我们把它干掉&#xff0c;重新分区&#xff01; 2、解除挂载 umount /homeE 没保存跳转到&…

Oracle 11g完全卸载教程(Windows)

文章目录 一、停止Oracle服务二、卸载Oracle1、卸载Oracle产品2、删除注册表3、删除环境变量以及其余文件 一、停止Oracle服务 进入服务 找到服务中的Oracle服务并且停止 全部停止运行成功 二、卸载Oracle 1、卸载Oracle产品 点击开始菜单找到Oracle&#xff0c;然后点击…

cobaltstrike 流量隐藏

云函数 新建一个云函数&#xff0c;在代码位置进行修改 首先导入 yisiwei.zip 的云函数包 PYTHON # -*- coding: utf8 -*- import json, requests, base64def main_handler(event, context):C2 https://49.xx.xx.xx # 这里可以使用 HTTP、HTTPS~下角标~ path event[path]h…

连续上榜|全息网御实力入选《中国网络安全行业全景图》

2024年4月12日&#xff0c;国内网络安全专业媒体安全牛正式发布第十一版《中国网络安全行业全景图》&#xff08;以下简称“全景图”&#xff09;。 本次全景图研究历时近4个月&#xff0c;共收到510家国内安全厂商4941项申报&#xff0c;实际收录2413项&#xff08;包含部分往…

如何把npm切换成yarn管理项目

1.删掉项目中package-lock.json和依赖包 这一步手动删掉就好 2.全局安装yarn npm install -g yarn 3.可以开始执行yarn install安装依赖 1&#xff09;执行yarn init 这一步是修改npm生成的package.json文件&#xff0c;可能会遇到这个问题&#xff1a; 这个查了一下是有…

电路笔记 : esp32pico-d4编程

安装 根据文章arduino ESP32 001 从零开始点亮小灯&#xff0c;安装相关软件依赖。 串口驱动 arduino安装 安装完arduino&#xff0c;需要安装esp32相关的开发依赖 不要选Arduino ESP32 Boards&#xff08;选下边那个&#xff09;,它对应的是背景图片里的板子 网络问题 关…

git报错

这里写自定义目录标题 git报错Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. 有一个原因就是在github上设置对应密钥时&#xff0c;有一个key获取应该设置为…

Docker部署MongoDB数据库

文章目录 官网地址docker 网络mongod.conf部署 MongoDB部署 mongo-expressdocker-compose.ymlMongoDB shell 官网地址 https://www.mongodb.com/zh-cn docker 网络 # 创建 mongo_network 网络 docker network create mongo_network # 查看网络 docker network list # 容器连…

【鸿蒙开发】第二十一章 Media媒体服务(一)

1 简介 Media Kit&#xff08;媒体服务&#xff09;提供了AVPlayer和AVRecorder用于播放、录制音视频。 在Media Kit的开发指导中&#xff0c;将介绍各种涉及音频、视频播放或录制功能场景的开发方式&#xff0c;指导开发者如何使用系统提供的音视频API实现对应功能。比如使用…

Windows安装Ollama结合内网穿透实现公网访问本地大语言模型Web交互界面

目录 ⛳️推荐 前言 1. 运行Ollama 2. 安装Open WebUI 2.1 在Windows系统安装Docker 2.2 使用Docker部署Open WebUI 3. 安装内网穿透工具 4. 创建固定公网地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍…

Java+Selenium自动化测试环境搭建

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 本主要介绍以Java为基础&#xff0c;搭建Selenium自动化…

操作系统-一个学习能力的新高度

目录 一、目标二、计划三、完成情况四、提升改进(最少3点)五、意外之喜(最少2点)六、总结 一、目标 通过考试&#xff0c;当然这是眼前目标&#xff1b;通过对知识的学习&#xff0c;补上在计算机中那些透明的东西&#xff0c;从而让知识可以按照逻辑一层一层的构建知识大厦&a…
最新文章