C语言合并两个带头节点升序排列链表

下面我将为你详细讲解“C语言合并两个带头节点升序排列链表”的完整攻略。

问题描述

假设有两个带头节点的升序排列链表,现在需要将它们合并成一个新的升序排列链表。

解决方案

  1. 定义一个新的链表来存储合并后的结果,定义三个指针分别指向两个输入链表的头节点和新链表的尾节点。

  2. 循环比较两个链表的当前节点,将较小的节点接入新链表的尾部,并将新链表的尾节点指向新加入的节点。

  3. 如果一个链表为空,直接将另一个链表的剩余节点加入新链表的尾部即可。

  4. 最后返回新链表的头节点即为合并后的结果。

下面是基于上述方案的代码实现:

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
    int value;
    struct node *next;
} Node;

/**
 * 合并两个带头节点升序排列链表
 * @param h1 第一个链表的头节点
 * @param h2 第二个链表的头节点
 * @return 合并后的升序排列链表的头节点
 */
Node *merge_sorted_lists(Node *h1, Node *h2) {
    Node *head = (Node *) malloc(sizeof(Node)); // 新链表的头节点
    Node *tail = head; // 新链表的尾节点,初始指向头节点
    Node *p1 = h1->next; // 第一个链表的当前节点
    Node *p2 = h2->next; // 第二个链表的当前节点

    // 循环比较两个链表的当前节点
    while (p1 != NULL && p2 != NULL) {
        if (p1->value < p2->value) {
            // 将较小的节点接入新链表的尾部
            tail->next = p1;
            tail = tail->next;
            p1 = p1->next;
        } else {
            tail->next = p2;
            tail = tail->next;
            p2 = p2->next;
        }
    }

    // 如果一个链表为空,直接将另一个链表的剩余节点加入新链表的尾部
    if (p1 != NULL) {
        tail->next = p1;
    }

    if (p2 != NULL) {
        tail->next = p2;
    }

    // 返回新链表的头节点即为合并后的结果
    return head;
}

int main() {
    // 示例1
    Node *h1 = (Node *) malloc(sizeof(Node)); // 第一个链表的头节点
    h1->next = NULL;
    Node *p1 = NULL; // 第一个链表的尾节点
    for (int i = 1; i <= 3; i++) {
        Node *node = (Node *) malloc(sizeof(Node));
        node->value = i * 2 - 1;
        node->next = NULL;
        if (p1 == NULL) {
            h1->next = node;
        } else {
            p1->next = node;
        }
        p1 = node;
    }

    Node *h2 = (Node *) malloc(sizeof(Node)); // 第二个链表的头节点
    h2->next = NULL;
    Node *p2 = NULL; // 第二个链表的尾节点
    for (int i = 1; i <= 4; i++) {
        Node *node = (Node *) malloc(sizeof(Node));
        node->value = i * 2;
        node->next = NULL;
        if (p2 == NULL) {
            h2->next = node;
        } else {
            p2->next = node;
        }
        p2 = node;
    }

    Node *head = merge_sorted_lists(h1, h2);
    Node *p = head->next;
    while (p != NULL) {
        printf("%d ", p->value);
        p = p->next;
    }
    printf("\n");

    // 示例2
    Node *h3 = (Node *) malloc(sizeof(Node)); // 第三个链表的头节点
    h3->next = NULL;
    Node *q1 = NULL; // 第三个链表的尾节点
    for (int i = 1; i <= 3; i++) {
        Node *node = (Node *) malloc(sizeof(Node));
        node->value = i * 2;
        node->next = NULL;
        if (q1 == NULL) {
            h3->next = node;
        } else {
            q1->next = node;
        }
        q1 = node;
    }

    Node *h4 = (Node *) malloc(sizeof(Node)); // 第四个链表的头节点
    h4->next = NULL;
    Node *q2 = NULL; // 第四个链表的尾节点
    for (int i = 1; i <= 3; i++) {
        Node *node = (Node *) malloc(sizeof(Node));
        node->value = i * 2 - 1;
        node->next = NULL;
        if (q2 == NULL) {
            h4->next = node;
        } else {
            q2->next = node;
        }
        q2 = node;
    }

    Node *head2 = merge_sorted_lists(h3, h4);

    Node *q = head2->next;
    while (q != NULL) {
        printf("%d ", q->value);
        q = q->next;
    }

    return 0;
}

示例说明

这里提供两个示例:

  1. 示例1中存在两个输入链表,分别为{1,3,5}和{2,4,6,8},合并后的升序排列链表为{1,2,3,4,5,6,8}。

  2. 示例2中存在两个输入链表,分别为{2,4,6}和{1,3,5},合并后的升序排列链表为{1,2,3,4,5,6}。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言合并两个带头节点升序排列链表 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Java数据结构实现二维数组与稀疏数组转换详解

    Java数据结构实现二维数组与稀疏数组转换详解 一、二维数组与稀疏数组 在介绍二维数组与稀疏数组的转换之前,需要先了解它们的定义和特点。 1.二维数组 二维数组是一个由多个一维数组组成的数组。可以将它理解为是一个由行和列构成的矩阵。其中,行和列的数量是固定的,而且必须预先指定。 二维数组的声明方式为: 数据类型[][] 数组名; 例: int[][] arr…

    other 2023年6月27日
    00
  • jQuery中removeClass()方法用法实例

    jQuery中removeClass()方法用法实例攻略 1. 概述 removeClass()方法是jQuery中用于移除指定元素的一个或多个类的方法。通过该方法,我们可以轻松地从元素中删除指定的类,从而改变元素的样式和行为。 2. 语法 .removeClass(className) 参数说明:- className:要移除的一个或多个类名,可以使用空格…

    other 2023年6月28日
    00
  • Ledger钱包初始化图文教程

    以下是“Ledger钱包初始化图文教程”的完整攻略: 前言 Ledger是一种硬件钱包,通过将私钥存储在离线设备中保证了资产安全。在使用Ledger之前,需要先进行初始化,设置一些基本信息并创建一个钱包。本教程将详细介绍如何初始化Ledger钱包。 初始化Ledger步骤 步骤一:打开Ledger Live 在计算机上打开Ledger Live应用程序。 步…

    other 2023年6月20日
    00
  • protobuf枚举使用

    Protobuf枚举使用 Protobuf是一种轻量级的数据交换格式,它可以用于序列化结构化数据。枚举是Protobuf中的一种数据类型,它可以用于定义一组有限的值。以下是Protobuf枚举使用的完整攻略。 步骤 以下是Protobuf枚举使用的步骤: 定义枚举类型。 在消息中使用枚举类型。 在代码中使用枚举类型。 示例 以下是两个示例,演示如何使用Pro…

    other 2023年5月6日
    00
  • 全新Win11体验已发布,亚马逊应用商店预览版新增 1000 多个安卓 App,任务栏支持天气

    全新Win11体验已发布,亚马逊应用商店预览版新增 1000 多个安卓 App,任务栏支持天气 Win11体验全新升级 Windows 11 是全新一代 Windows 操作系统,由 Microsoft 公司于 2021 年 6 月 24 日首次发布,主打简洁、美观、高效等特点。Win11将为用户提供更加流畅、友好的操作体验、以及全新的用户界面。 下面我们来…

    other 2023年6月25日
    00
  • Java基础之方法重写详解

    Java 基础之方法重写详解 什么是方法重写? 在 Java 中,方法重写是指子类中定义了和父类中方法名称、参数列表以及返回值类型均相同的一个方法,并且该子类中这个方法的访问权限要大于等于父类中此方法的访问权限。当调用该方法时,子类对象会优先执行自身中的方法,而不是执行父类中的同名方法。 方法重写的注意事项 在进行方法重写的时候,需要注意以下几点: 方法名称…

    other 2023年6月26日
    00
  • 微信开发者工具怎么修改内存限制?微信开发者工具修改内存限制教程

    微信开发者工具怎么修改内存限制 微信开发者工具默认内存限制是500MB,对于部分复杂应用或者大型项目可能会出现内存不足的情况,需要修改内存限制来提高开发效率。 修改内存限制步骤 打开微信开发者工具,选择菜单栏的“设置”。 在设置页面中,找到“关于”选项卡。 在“关于”选项卡中找到“其他设置”中的“启动参数”。 在启动参数中添加–max-old-space-…

    other 2023年6月26日
    00
  • Windows的sc命令详解(sc命令用法)

    Windows的sc命令详解 sc是Windows操作系统中的一个命令行工具,用于管理Windows服务。它的主要作用是查询、创建、修改和删除服务,以及对服务进行启动、停止和暂停等操作。本文将详细介绍sc命令的用法。 查询服务 要查询系统中所有的服务,可以使用以下命令: sc query 该命令会输出一个服务列表,其中包括各个服务的名称、状态、启动类型和进程…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部