C语言CreateLink函数如何创建链接?

99ANYc3cd6
预计阅读时长 22 分钟
位置: 首页 C语言 正文

什么是链表?

链表是一种线性数据结构,但它与数组不同,数组在内存中是连续存储的,而链表的元素(称为“节点”)在内存中是非连续存储的。

c语言createlink
(图片来源网络,侵删)

每个节点都包含两部分:

  1. 数据域:存储实际的数据。
  2. 指针域:存储指向下一个节点的内存地址。

通过指针域,这些节点像一串链条一样连接起来,形成链表,链表的第一个节点称为头节点,最后一个节点的指针域通常指向 NULL,表示链表的结束。

一个简单的节点结构示意图:

  +-------+--------+      +-------+--------+      +-------+--------+
  | Data  |  Next  |----->| Data  |  Next  |----->| Data  |  NULL  |
  +-------+--------+      +-------+--------+      +-------+--------+
      Node 1                  Node 2                  Node 3

创建链表的步骤

创建链表通常有两种方式:

c语言createlink
(图片来源网络,侵删)
  • 头插法:新节点总是插入到链表的头部,最终链表的节点顺序与输入顺序相反。
  • 尾插法:新节点总是插入到链表的尾部,最终链表的节点顺序与输入顺序一致。

下面我们分别用这两种方法来实现 createlink 函数。


准备工作:定义节点结构

在创建链表之前,我们必须先定义节点的结构。

#include <stdio.h>
#include <stdlib.h> // 需要用到 malloc 和 free
// 定义链表节点结构体
typedef struct Node {
    int data;           // 数据域,这里我们用 int 类型作为示例
    struct Node* next;  // 指针域,指向下一个节点
} Node;
  • typedefstruct Node 定义了一个别名 Node,使得代码更简洁。
  • data 用来存储数据。
  • next 是一个指向 Node 结构体的指针,用于连接下一个节点。

方法一:头插法创建链表

思路

  1. 创建一个新节点。
  2. 将新节点的 next 指针指向当前的链表头。
  3. 更新链表头,使其指向这个新节点。

特点:实现简单,效率高(O(1)时间复杂度),但最终链表的顺序与输入顺序相反。

c语言createlink
(图片来源网络,侵删)

代码实现:

// 函数:头插法创建链表
// 参数:无
// 返回值:返回创建好的链表的头节点指针
Node* createLinkByHeadInsert() {
    Node* head = NULL; // 初始化头节点为 NULL,表示一个空链表
    int value;
    printf("请输入节点数据(输入-1结束):\n");
    while (1) {
        scanf("%d", &value);
        if (value == -1) {
            break; // 输入-1表示结束创建
        }
        // 1. 创建新节点
        Node* newNode = (Node*)malloc(sizeof(Node));
        if (newNode == NULL) {
            printf("内存分配失败!\n");
            exit(1); // 内存分配失败,退出程序
        }
        newNode->data = value;
        newNode->next = NULL;
        // 2. 将新节点插入到链表头部
        newNode->next = head; // 新节点的 next 指向原来的头
        head = newNode;       // 更新头节点为新节点
    }
    return head; // 返回创建好的链表的头
}

方法二:尾插法创建链表

思路

  1. 除了需要一个 head 指针指向链表头,还需要一个 tail 指针始终指向链表的最后一个节点。
  2. 创建一个新节点。
  3. tail 指针的 next 指向这个新节点。
  4. 更新 tail 指针,使其指向这个新节点。

特点:能保持输入顺序,但需要额外的 tail 指针来追踪尾部,实现比头插法稍复杂。

代码实现:

// 函数:尾插法创建链表
// 参数:无
// 返回值:返回创建好的链表的头节点指针
Node* createLinkByTailInsert() {
    Node* head = NULL;  // 链表头
    Node* tail = NULL;  // 链表尾,初始时为 NULL
    int value;
    printf("请输入节点数据(输入-1结束):\n");
    while (1) {
        scanf("%d", &value);
        if (value == -1) {
            break;
        }
        // 1. 创建新节点
        Node* newNode = (Node*)malloc(sizeof(Node));
        if (newNode == NULL) {
            printf("内存分配失败!\n");
            exit(1);
        }
        newNode->data = value;
        newNode->next = NULL;
        // 2. 将新节点插入到链表尾部
        if (head == NULL) {
            // 如果是第一个节点,头和尾都指向它
            head = newNode;
            tail = newNode;
        } else {
            // 如果不是第一个节点,将当前尾节点的 next 指向新节点
            tail->next = newNode;
            // 更新尾节点为新节点
            tail = newNode;
        }
    }
    return head; // 返回创建好的链表的头
}

完整示例代码

下面是一个完整的 C 程序,它包含了链表的创建、打印和内存释放。

#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
typedef struct Node {
    int data;
    struct Node* next;
} Node;
// --- 函数声明 ---
Node* createLinkByHeadInsert();
Node* createLinkByTailInsert();
void printLink(Node* head);
void freeLink(Node* head);
int main() {
    // 使用头插法创建链表
    printf("--- 使用头插法创建链表 ---\n");
    Node* head1 = createLinkByHeadInsert();
    printf("创建的链表为:");
    printLink(head1);
    freeLink(head1);
    printf("\n---------------------------------\n\n");
    // 使用尾插法创建链表
    printf("--- 使用尾插法创建链表 ---\n");
    Node* head2 = createLinkByTailInsert();
    printf("创建的链表为:");
    printLink(head2);
    freeLink(head2);
    return 0;
}
// --- 函数定义 ---
/**
 * @brief 头插法创建链表
 */
Node* createLinkByHeadInsert() {
    Node* head = NULL;
    int value;
    while (1) {
        scanf("%d", &value);
        if (value == -1) break;
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = value;
        newNode->next = head;
        head = newNode;
    }
    return head;
}
/**
 * @brief 尾插法创建链表
 */
Node* createLinkByTailInsert() {
    Node* head = NULL;
    Node* tail = NULL;
    int value;
    while (1) {
        scanf("%d", &value);
        if (value == -1) break;
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = value;
        newNode->next = NULL;
        if (head == NULL) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
    }
    return head;
}
/**
 * @brief 打印链表
 * @param head 链表的头节点
 */
void printLink(Node* head) {
    Node* current = head;
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}
/**
 * @brief 释放链表内存
 * @param head 链表的头节点
 */
void freeLink(Node* head) {
    Node* current = head;
    while (current != NULL) {
        Node* temp = current; // 临时保存当前节点
        current = current->next; // 移动到下一个节点
        free(temp); // 释放当前节点的内存
    }
    printf("链表内存已释放,\n");
}

如何编译和运行

  1. 将上面的代码保存为 create_list.c 文件。
  2. 打开终端或命令提示符,使用 GCC 进行编译:
    gcc create_list.c -o create_list
  3. 运行生成的可执行文件:
    • 在 Windows 上:create_list.exe
    • 在 Linux/macOS 上:./create_list

运行示例(以尾插法为例):

--- 使用尾插法创建链表 ---
请输入节点数据(输入-1结束):
10
20
30
-1
创建的链表为:10 -> 20 -> 30 -> NULL
链表内存已释放。
  • createlink 是一个概念,指代创建链表的操作,通常由一个自定义函数实现。
  • 创建链表的核心是动态分配内存 (malloc) 来创建节点,并通过指针 (->) 将它们连接起来。
  • 头插法简单快速,但顺序会反转。
  • 尾插法能保持顺序,但需要维护一个尾指针。
  • 非常重要:使用 malloc 动态分配的内存在程序结束前不会自动释放,必须使用 free 函数手动释放,否则会造成内存泄漏freeLink 函数就是用来完成这个任务的。
-- 展开阅读全文 --
头像
dede新闻网站梦模板如何使用?
« 上一篇 昨天
HTML5如何改造织梦标签?
下一篇 » 昨天

相关文章

取消
微信二维码
支付宝二维码

目录[+]