【数据结构---C语言】一分钟带你学会链表

只教一遍,睁大看好了!!!

以下为线性表------链表---->>头插法

#include <stdio.h>  // 引入标准输入输出库
#include <stdlib.h> // 引入标准库,包含malloc和exit等函数

// 定义链表节点的结构体
typedef struct link {
    int data;        // 节点存储的数据
    struct link* next; // 指向下一个节点的指针
} link;

// 创建链表的函数
link* CreateList() {
    link* head, *p; // head指向头节点,p用于创建新节点
    head = (link*)malloc(sizeof(link)); // 分配头节点的内存
    if (head == NULL) { // 检查内存是否分配成功
        printf("内存分配失败!\n");
        exit(0); // 如果失败,则打印错误信息并退出程序
    }
    head->next = NULL; // 初始化头节点的next指针为NULL

    // 提示用户输入结束标志
    printf("**********请输入 '000' 结束程序***********\n");
    
    while (1) { // 无限循环,直到用户输入结束标志
        int x;
        scanf_s("%d", &x); // 从用户那里读取一个整数
        if (x == 0) { // 检查是否是结束标志
            break; // 如果是,则退出循环
        }
        p = (link*)malloc(sizeof(link)); // 为新节点分配内存
        if (p == NULL) { // 检查内存是否分配成功
            printf("内存分配失败!\n");
            exit(0); // 如果失败,则打印错误信息并退出程序
        }
        p->data = x; // 将用户输入的数据存储到新节点
        p->next = head->next; // 将新节点插入到链表的头部
        head->next = p; // 更新头节点的next指针
    }
    return head; // 返回头节点的指针
}

// 打印链表的函数
void PrintList(link* L) {
    link* list = L->next; // 从头节点的下一个节点开始打印,即不打印头节点
    // 如果要打印头节点,可以使用下面的行代替上面的行
    // link* list = L; // 从头节点开始打印,即打印头节点
    
    while (list != NULL) { // 循环直到链表结束
        printf("%-4d", list->data); // 打印当前节点的数据
        list = list->next; // 移动到下一个节点
    }
}

// 主函数
int main() {
    link* L; // 声明一个指向链表头节点的指针
    L = CreateList(); // 创建链表
    PrintList(L); // 打印链表
    return 0; // 程序结束
}

以下为线性表------链表---->>尾插法

#include <stdio.h>  // 引入标准输入输出库
#include <stdlib.h> // 引入标准库,包含malloc和exit等函数

// 定义链表节点的结构体
typedef struct link {
    int data;        // 节点存储的数据
    struct link* next; // 指向下一个节点的指针
} link;

// 创建链表的函数
link* CreateList() {
    link* head, * p, * q; // head指向头节点,p用于创建新节点,q用于追踪链表的最后一个节点
    head = (link*)malloc(sizeof(link)); // 分配头节点的内存
    if (head == NULL) { // 检查内存是否分配成功
        printf("内存分配失败!\n");
        exit(0); // 如果失败,则打印错误信息并退出程序
    }
    head->next = NULL; // 初始化头节点的next指针为NULL
    q = head; // q初始指向头节点,用于跟踪链表的最后一个节点

    // 提示用户输入结束标志
    printf("**********请输入 “000” 结束程序***********\n");
    
    while (1) { // 无限循环,直到用户输入结束标志
        int x;
        scanf_s("%d", &x); // 从用户那里读取一个整数
        if (x == 0) break; // 如果用户输入0,则结束循环
        p = (link*)malloc(sizeof(link)); // 为新节点分配内存
        if (p == NULL) { // 检查内存是否分配成功
            printf("内存分配失败!\n");
            exit(0); // 如果失败,则打印错误信息并退出程序
        }
        p->data = x; // 将用户输入的数据存储到新节点
        q->next = p; // 将新节点链接到链表的末尾
        q = p; // 更新q,使其指向链表的最后一个节点
    }
    q->next = NULL; // 确保链表末尾的next指针为NULL
    return head; // 返回头节点的指针
}

// 打印链表的函数
void PrintList(link* L) {
    link* list = L->next; // 从头节点的下一个节点开始打印,即不打印头节点
    // 如果要打印头节点,可以使用下面的行代替上面的行
    // link* list = L; // 从头节点开始打印,即打印头节点
    
    while (list != NULL) { // 循环直到链表结束
        printf("%-4d", list->data); // 打印当前节点的数据
        list = list->next; // 移动到下一个节点
    }
}

// 主函数
int main() {
    link* L; // 声明一个指向链表头节点的指针
    L = CreateList(); // 创建链表
    PrintList(L); // 打印链表
    return 0; // 程序结束
}

以下为线性表------链表---->>完整单链表

#include <stdio.h>  // 引入标准输入输出库
#include <stdlib.h> // 引入标准库,包含malloc和exit等函数

// 定义链表节点的结构体
typedef struct link {
    int data;        // 节点存储的数据
    struct link* next; // 指向下一个节点的指针
} link;

// 创建链表的函数
link* CreateList() {
    link* head, * p, * q;
    head = (link*)malloc(sizeof(link)); // 分配头节点的内存
    if (head == NULL) { // 检查内存是否分配成功
        printf("内存分配失败!\n");
        exit(0); // 如果失败,则打印错误信息并退出程序
    }
    head->next = NULL; // 初始化头节点的next指针为NULL
    q = head; // q初始指向头节点,用于跟踪链表的最后一个节点

    // 提示用户输入结束标志
    printf("**********请输入 “000” 结束程序***********\n");
    
    while (1) { // 无限循环,直到用户输入结束标志
        int x;
        scanf_s("%d", &x); // 从用户那里读取一个整数
        if (x == 0) break; // 如果用户输入0,则结束循环
        p = (link*)malloc(sizeof(link)); // 为新节点分配内存
        if (p == NULL) { // 检查内存是否分配成功
            printf("内存分配失败!\n");
            exit(0); // 如果失败,则打印错误信息并退出程序
        }
        p->data = x; // 将用户输入的数据存储到新节点
        q->next = p; // 将新节点链接到链表的末尾
        q = p; // 更新q,使其指向链表的最后一个节点
    }
    q->next = NULL; // 确保链表末尾的next指针为NULL
    return head; // 返回头节点的指针
}

// 插入链表的函数
void InsertList(link* head, int value) {
    link* p, * q, *r;
    r = (link*)malloc(sizeof(link)); // 为新节点分配内存
    if (r == NULL) { // 检查内存是否分配成功
        printf("内存分配失败\n");
        exit(0);
    }
    r->data = value; // 设置新节点的数据
    p = head;
    q = head->next;
    // 找到正确的插入位置
    while (q != NULL && q->data < value) {
        p = q;
        q = q->next;
    }
    // 将新节点插入到p之后
    p->next = r;
    r->next = q;
}

// 删除链表节点的函数
void DeleteList(link* head, int all) {
    link* p, *q;
    p = head;
    q = head->next;
    // 遍历链表寻找要删除的节点
    while (q != NULL) {
        if (q->data == all) { // 如果找到要删除的节点
            p->next = q->next; // 删除节点
            free(q); // 释放内存
            return; // 完成删除操作后返回
        }
        else {
            p = q;
            q = q->next;
        }
    }
}

// 打印链表的函数
void PrintList(link* L) {
    link* list = L->next; // 从头节点的下一个节点开始打印,即不打印头节点
    while (list != NULL) { // 循环直到链表结束
        printf("%-4d", list->data); // 打印当前节点的数据
        list = list->next; // 移动到下一个节点
    }
}

// 主函数
int main() {
    link* L;
    L = CreateList(); // 创建链表
    printf("该链表为:");
    PrintList(L); 
    printf("\n");

    // 插入数据
    printf("**********数据插入***********\n");
    int value;
    while (1) {
        scanf_s("%d", &value);
        if (value == 0) break; // 如果用户输入0,则结束插入
        printf("链表插入:%d\n", value);
        InsertList(L, value);
        PrintList(L);
        printf("\n");
    }

    // 删除数据
        printf("**********数据删除***********\n");
    int all;
    while (1) {
        scanf_s("%d", &all);
        if (all == 0) break; // 如果用户输入0,则结束删除
        printf("链表删除:%d\n", all);
        DeleteList(L, all);
        PrintList(L);
        printf("\n");
    }

    // 打印最终的链表
    printf("最终链表打印:\n");
    PrintList(L);
    return 0;
}

好了,本节课结束,下课!!!

各位童鞋们都学废了吗???

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值