2401_88005412 2025-11-21 21:16 采纳率: 0%
浏览 13

林业生长监测数据链表分解与达标统计

林业部门通过分布式监测站点采集某林场的树木年度生长偏差值(单位:cm),所有监测数据通过带头结点的单链表A存储。生长偏差值的物理含义如下(以林场树种标准年生长量为基准):

负数:实际生长量低于标准生长量(生长不足,需启动针对性养护措施,如施肥、病虫害防治);
正数:实际生长量超出标准生长量(生长过旺,需进行适度疏伐,避免资源竞争过度);
0:实际生长量刚好符合标准生长量(生长达标,无需额外干预)。
现需设计一个算法,完成以下任务:将链表A分解为两个带头结点的单链表B和C,其中B表仅存储“生长不足”的偏差值(即结点值小于 0),C 表仅存储“生长过旺”的偏差值(即结点值大于 0)。

编程要求
输入
多组数据,每组数据有两行,第一行为链表A的长度n,第二行为链表A的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出
对于每组数据分别输出两行,分别对应链表B和C的元素,每个数据之间用空格分隔。

测试说明
平台会对你编写的代码进行测试:

测试输入:
9
3 -6 1 0 -2 4 0 -3 8
11
2 5 0 3 -1 -2 0 2 0 6 -1
0

预期输出:
-6 -2 -3
3 1 4 8
-1 -2 -1
2 5 3 2 6

  • 写回答

5条回答 默认 最新

  • 檀越@新空间 2025-11-21 21:42
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    好的,我们来详细分析这个问题,并提供一个完整的解决方案。


    问题描述

    我们需要将带头结点的单链表A分解为两个新链表B和C:

    • 链表B:存储所有值小于0的节点(生长不足);
    • 链表C:存储所有值大于0的节点(生长过旺);

    输入是多组数据,每组包含链表A的长度n和n个元素。当n=0时,输入结束。

    输出是两行,分别对应链表B和C的元素,按顺序排列。


    解决方案

    1. 数据结构设计

    由于题目中提到的是带头结点的单链表,我们可以使用如下结构定义:

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

    其中:

    • data 存储数值;
    • next 指向下一个节点。

    2. 算法步骤

    我们将按照以下步骤完成链表的分解:

    步骤一:初始化链表

    根据输入的n和数组,构建带头结点的链表A。

    步骤二:遍历链表A

    逐个访问链表A中的每个节点,判断其值是否小于0或大于0。

    步骤三:拆分链表

    • 如果值小于0,则插入到链表B;
    • 如果值大于0,则插入到链表C;
    • 值为0的节点被忽略。

    步骤四:输出结果

    将链表B和C的元素按顺序输出,空格分隔。


    3. 代码实现(C语言)

    #include <stdio.h>
    #include <stdlib.h>
    
    // 定义链表结构体
    typedef struct Node {
        int data;
        struct Node *next;
    } Node, *LinkList;
    
    // 创建带头结点的链表
    LinkList createList(int n, int arr[]) {
        LinkList head = (LinkList)malloc(sizeof(Node));
        head->next = NULL;
        Node *current = head;
        
        for (int i = 0; i < n; i++) {
            Node *newNode = (Node *)malloc(sizeof(Node));
            newNode->data = arr[i];
            newNode->next = NULL;
            current->next = newNode;
            current = current->next;
        }
        
        return head;
    }
    
    // 分解链表
    void splitList(LinkList A, LinkList *B, LinkList *C) {
        *B = (LinkList)malloc(sizeof(Node));
        (*B)->next = NULL;
        *C = (LinkList)malloc(sizeof(Node));
        (*C)->next = NULL;
    
        Node *p = A->next;
        Node *bTail = *B;
        Node *cTail = *C;
    
        while (p != NULL) {
            if (p->data < 0) {
                // 插入到B链表
                p->next = bTail->next;
                bTail->next = p;
                bTail = p;
            } else if (p->data > 0) {
                // 插入到C链表
                p->next = cTail->next;
                cTail->next = p;
                cTail = p;
            }
            p = p->next;
        }
    }
    
    // 输出链表
    void printList(LinkList list) {
        Node *p = list->next;
        while (p != NULL) {
            printf("%d ", p->data);
            p = p->next;
        }
        printf("\n");
    }
    
    int main() {
        int n;
        while (scanf("%d", &n) != EOF && n != 0) {
            int arr[n];
            for (int i = 0; i < n; i++) {
                scanf("%d", &arr[i]);
            }
    
            // 构建链表A
            LinkList A = createList(n, arr);
    
            // 分解链表
            LinkList B, C;
            splitList(A, &B, &C);
    
            // 输出结果
            printList(B);
            printList(C);
    
            // 释放内存(可选)
            // freeList(A); 
            // freeList(B);
            // freeList(C);
        }
    
        return 0;
    }
    

    4. 代码说明

    • createList函数:根据输入数组创建带头结点的链表。
    • splitList函数:遍历链表A,将符合条件的节点分别插入到B和C链表中。
    • printList函数:打印链表中的元素,以空格分隔。
    • 主函数:读取输入并处理每组数据。

    5. 测试输入与输出示例

    测试输入:

    9
    3 -6 1 0 -2 4 0 -3 8
    11
    2 5 0 3 -1 -2 0 2 0 6 -1
    0
    

    预期输出:

    -6 -2 -3 
    3 1 4 8 
    -1 -2 -1 
    2 5 3 2 6 
    

    6. 注意事项

    • 链表在程序结束后应释放内存,避免内存泄漏(本示例中未展示)。
    • 若需要支持多组测试数据,请确保每次循环都重新初始化链表。
    • 输入格式必须严格按照题意,否则可能导致错误。

    如果你有其他编程语言(如Python、Java)的需求,也可以告诉我,我可以为你提供对应的实现版本。

    评论

报告相同问题?

问题事件

  • 创建了问题 11月21日