C语言单链表尾插法创建、遍历输出与节点求和实战

Leo
Leo
发布时间:2026-10-15 | 4人浏览过
原创

在C语言数据结构的实际操作中,单链表的创建方式直接决定了节点的排列顺序,而遍历则是进行数据展示与聚合运算的基础。本文通过两个具体案例,分别演示如何利用尾插法构建按输入顺序排列的单链表并进行遍历输出,以及如何遍历链表完成数值的累加求和。

按顺序创建与遍历单链表

在实际开发或算法题中,如果要求输出的结果顺序必须与输入的数组顺序保持一致(即先输入的节点排在链表前端),则必须使用尾插法来构建链表。头插法虽然简单,但会导致链表节点顺序与输入顺序完全相反。

第1步:定义链表结构体与初始化

首先定义包含数据域和指针域的节点结构体,并创建一个带空头结点的链表,以便统一后续操作逻辑。

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

typedef int DataType;
typedef struct LinkList {
    DataType data;         // 建议命名为data而非x,语义更清晰
    struct LinkList *next;
}LinkList;

// 初始化链表(带头结点)
LinkList* InitLinkList() {
    LinkList* head = (LinkList*)malloc(sizeof(LinkList));
    if (!head) return NULL;
    head->next = NULL;
    return head;
}

第2步:使用尾插法构建链表

遍历循环读取输入值,每次申请新节点并将其链接到当前链表的末尾,保持 last 指针始终指向尾节点。

void CreateListL(LinkList* head, int n) {
    LinkList* s;
    LinkList* last = head; // last始终指向链表最后一个节点
    
    for (int i = 0; i < n; i++) {
        s = (LinkList*)malloc(sizeof(LinkList));
        if (s) {
            scanf("%d", &s->data);
            s->next = NULL;
            last->next = s;  // 将新节点接入尾部
            last = s;        // 更新尾节点指针
        }
    }
}

第3步:遍历并打印节点值

从首结点的下一个节点开始,依次访问每个节点直到为空,将数据打印出来。

void PrintList(LinkList* head) {
    LinkList* p = head->next;
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main() {
    int n;
    scanf("%d", &n);           // 输入节点数量
    LinkList* S = InitLinkList();
    CreateListL(S, n);         // 创建链表
    PrintList(S);              // 顺序输出
    return 0;
}

关键点:此场景下输入样例为 5 4 2 1,使用上述代码输出结果依然为 5 4 2 1。若改用头插法,输出将变为逆序的 1 2 4 5,这与通常的业务预期不符。

单链表的遍历与求和操作

当需求转变为计算链表内所有元素的总和时,无论采用头插法还是尾插法,最终的物理存储顺序虽不同,但集合元素相同,其累加结果保持一致。因此,此时的核心在于实现一个通用的遍历累加逻辑。

第1步:初始化与创建(通用型)

此处可沿用上述初始化函数。创建函数 CreatLinkL 的逻辑与前文一致,支持动态数量的节点录入。

第2步:实现遍历求和算法

在遍历过程中,维护一个整型变量 sum,将其初始化为0,每访问一个节点就将其数据域累加到 sum 中。

void GetSum(LinkList* head) {
    LinkList* p = head->next;
    int sum = 0;
    
    while (p != NULL) {
        sum += p->data;  // 累加节点值
        p = p->next;
    }
    printf("%d\n", sum);
}

第3步:主函数调用与执行

int main() {
    LinkList* s = InitLinkList();
    int n;
    scanf("%d", &n);
    CreatLinkL(s, n);      // 创建过程不影响最终求和结果
    GetSum(s);             // 执行求和
    return 0;
}

注意:在 GetSum 函数中,我们并未改变节点的值,而是进行了临时的加法运算。这体现了算法设计中“只读遍历”的思想,保证了原数据的完整性。

常见问题与排错

  • 内存泄漏:在分配 malloc 后未检查返回值是否为 NULL,可能导致空指针访问崩溃。生产环境中应增加判空语句。
  • 非法参数:输入的 n 为负数或未提供,可能导致死循环或无效内存读写。建议在 main 入口处增加逻辑判断。
  • 释放资源:程序结束前务必编写释放链表内存的代码,防止长时间运行的服务产生内存堆积。

总结

单链表的灵活之处在于其动态性,但这也要求开发者必须清晰管理指针关系。尾插法是保持数据输入顺序不变的首选方案,而遍历累加则是处理结构化数据的最基本功。掌握这两项技能,便能为后续学习图论、哈希表等复杂数据结构打下坚实基础。以上就是C语言单链表尾插法创建、遍历与求和的详细内容,更多关于C语言链表编程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表