【重拾C语言】十三、动态数据组织(二)链表(创建、遍历检索、插入、删除、交换)

目录

前言

十三、动态数据组织

[13.1~2 动态数据组织、动态变量](#13.1~2 动态数据组织、动态变量)

[13.3 链表](#13.3 链表)

[13.3.1 单向链表---创建](#13.3.1 单向链表—创建)

[13.3.2 单向链表---遍历检索](#13.3.2 单向链表—遍历检索)

[13.3.3 单向链表---插入、删除与交换](#13.3.3 单向链表—插入、删除与交换)

[13.3.4 单向链表---例题](#13.3.4 单向链表—例题)

[13.3.5 栈和队列](#13.3.5 栈和队列)


前言

链表是一种常见的动态数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在C语言中,可以使用指针和动态内存分配函数来实现链表的创建、遍历、插入、删除和交换操作。

十三、动态数据组织

13.1~2 动态数据组织、动态变量

【重拾C语言】十三、动态数据组织_QomolangmaH的博客-CSDN博客https://blog.csdn.net/m0_63834988/article/details/133845135?spm=1001.2014.3001.5501

13.3 链表

13.3.1 单向链表---创建

创建一个单向链表的基本步骤包括定义节点结构和使用动态内存分配函数分配节点内存。节点结构通常包含两个成员:数据成员 (用于存储数据)和指针成员(用于指向下一个节点)。通过将节点链接在一起,形成链表的结构。

cpp 复制代码
// 定义节点结构
struct Node {
    int data;           // 数据成员
    struct Node* next;  // 指针成员
};

// 创建链表
struct Node* createLinkedList() {
    struct Node* head = NULL;  // 头指针,指向链表的第一个节点
    struct Node* temp = NULL;  // 临时指针,用于创建新节点
    
    // 创建节点1
    struct Node* node1 = (struct Node*)malloc(sizeof(struct Node));
    node1->data = 1;
    node1->next = NULL;
    
    // 将节点1设为头节点
    head = node1;
    
    // 创建节点2
    struct Node* node2 = (struct Node*)malloc(sizeof(struct Node));
    node2->data = 2;
    node2->next = NULL;
    
    // 将节点2链接到节点1后面
    node1->next = node2;
    
    // 创建节点3
    struct Node* node3 = (struct Node*)malloc(sizeof(struct Node));
    node3->data = 3;
    node3->next = NULL;
    
    // 将节点3链接到节点2后面
    node2->next = node3;
    
    return head;  // 返回头指针
}

13.3.2 单向链表---遍历检索

遍历链表的过程是按顺序访问链表中的每个节点,并执行相应的操作。通过使用一个指针依次指向链表中的节点,可以遍历整个链表。

cpp 复制代码
// 遍历链表并打印节点数据
void traverseLinkedList(struct Node* head) {
    struct Node* current = head;  // 从头节点开始遍历
    
    while (current != NULL) {
        printf("%d ", current->data);  // 打印节点数据
        current = current->next;      // 移动到下一个节点
    }
}

13.3.3 单向链表---插入、删除与交换

在链表中插入、删除和交换节点是常见的操作,可以通过更新节点的指针来实现。

cpp 复制代码
// 在链表中插入节点
void insertNode(struct Node* prevNode, int newData) {
    if (prevNode == NULL) {
        printf("Error: Previous node cannot be NULL.\n");
        return;
    }
    
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->data = newData;
    newNode->next = prevNode->next;
    prevNode->next = newNode;
}

// 在链表中删除节点
void deleteNode(struct Node* prevNode) {
    if (prevNode == NULL || prevNode->next == NULL) {
        printf("Error: Node to be deleted cannot be NULL.\n");
        return;
    }
    
    struct Node* nodeToDelete = prevNode->next;
    prevNode->next = nodeToDelete->next;
    free(nodeToDelete);  // 释放内存
}

// 在链表中交换两个节点的位置
void swapNodes(struct Node* head, int data1, int data2) {
    if (data1 == data2) {
        printf("Error: Data values are the same.\n");
        return;
    }
    
    struct Node* prevNode1 = NULL;
    struct Node* prevNode2 = NULL;
    struct Node* currentNode = head;
    
    while (currentNode != NULL) {
        if (currentNode->next != NULL && currentNode->next->data == data1)
            prevNode1 = currentNode;
        if (currentNode->next != NULL && currentNode->next->data == data2)
            prevNode2 = currentNode;
        
        currentNode = currentNode->next;
    }
    
    if (prevNode1 == NULL || prevNode2 == NULL) {
        printf("Error: Data values not found in the list.\n");
        return;
    }
    
    struct Node* node1 = prevNode1->next;
    struct Node* node2 = prevNode2->next;
    
    if (prevNode1 != NULL)
        prevNode1->next = node2;
    else
        head = node2;
    
    if (prevNode2 != NULL)
        prevNode2->next = node1;
    else
        head = node1;
    
    struct Node* temp = node1->next;
    node1->next = node2->next;
    node2->next = temp;
}

13.3.4 单向链表---例题

下面是一个示例,演示了如何使用单向链表来实现一个简单的任务列表:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

struct Task {
    char name[100];
    struct Task* next;
};

struct Task* createTask(const char* name) {
    struct Task* task = (struct Task*)malloc(sizeof(struct Task));
    strcpy(task->name, name);
    task->next = NULL;
    return task;
}

void addTask(struct Task** head, const char* name) {
    struct Task* newTask = createTask(name);
    if (*head == NULL) {
        *head = newTask;
    } else {
        struct Task* current = *head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newTask;
    }
}

void printTasks(struct Task* head) {
    struct Task* current = head;
    while (current != NULL) {
        printf("%s\n", current->name);
        current = current->next;
    }
}

int main() {
    struct Task* taskList = NULL;
    
    addTask(&taskList, "Task 1");
    addTask(&taskList, "Task 2");
    addTask(&taskList, "Task 3");
    
    printTasks(taskList);
    
    return 0;
}

13.3.5 栈和队列

除了链表,栈和队列也是常见的动态数据结构。栈是一种后进先出(LIFO)的数据结构,可以使用数组或链表来实现。队列是一种先进先出(FIFO)的数据结构,也可以使用数组或链表来实现。关于栈和队列的相关介绍详见后文。

相关推荐
geovindu几秒前
rust: Facade Pattern
开发语言·后端·设计模式·rust·外观模式
福大大架构师每日一题13 分钟前
Rust 1.99.0发布:C 可变参数、裸函数、Cargo 配置、Rustdoc 性能与大量兼容性调整全解析
c语言·开发语言·rust
智鸟科技GemeOpen开发者智能设备18 分钟前
平安校园 AI 智能实时告警系统 智鸟科技·GemeOpen + 谷华科技·融合创新方案白皮书
java·开发语言·python·物联网·智能家居
Wang's Blog38 分钟前
Java框架 SpringCloud 快速入门: Feign 的自定义配置与日志级别
java·开发语言·spring cloud
成旭先生1 小时前
企业全景信息查询 API:工商照面 33 项、股东出资、变更与社保一次查全
java·开发语言·api接口·企业信息查询·工商数据·风控尽调·供应商准入
2601_962885721 小时前
批量取数比循环单取快多少?用 AlphaFeed klines.batch给多股票取数提速
开发语言·php·batch
动词ing1 小时前
【C语言题目练习】算法 整数反转
c语言·开发语言·算法
多弗朗皮卡丘1 小时前
C++多继承
开发语言·c++·多继承
lie..1 小时前
30天从零开始学AI应用开发(Day 19):项目二完结:RAG 知识库问答系统,把自己攒的资料变成私人顾问
开发语言·人工智能·python
SWAGGY..1 小时前
【C++进阶】:(7)红黑树的原理与 C++ 实现:结构设计、插入调整及性质验证
android·java·开发语言·c++·算法