数据结构:链表-单向链表篇

链表,它由一系列节点(结构体) 组成,每个节点包含数据字段和指针 ,节点和节点之间通过指针连接在一起。与数组不同,链表中的元素在内存中不是连续存储的,而是通过指针连接在一起。

cpp 复制代码
// 单向链表节点定义
struct Node {
    int data;           // 数据字段
    struct Node* next;  // 指向下一个节点的指针
};

单向链表

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

// 定义链表节点结构
struct Node {
    int data;
    struct Node* next;
};

// 创建新节点的函数
struct Node* createNode(int data) {
    // 分配内存
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    
    // 检查内存分配是否成功
    if (newNode == NULL) {
        printf("内存分配失败!\n");
        exit(1);
    }
    
    // 初始化节点数据
    newNode->data = data;
    newNode->next = NULL;
    
    return newNode;
}

在链表头部插入节点

cpp 复制代码
// 在链表头部插入节点
struct Node* insertAtBeginning(struct Node* head, int data) {
    // 创建新节点
    struct Node* newNode = createNode(data);
    
    // 将新节点的next指向当前的头节点
    newNode->next = head;
    
    // 更新头节点为新节点
    return newNode;
}

在链表尾部插入节点

cpp 复制代码
// 在链表尾部插入节点
struct Node* insertAtEnd(struct Node* head, int data) {
    // 创建新节点
    struct Node* newNode = createNode(data);
    
    // 如果链表为空,新节点就是头节点
    if (head == NULL) {
        return newNode;
    }
    
    // 找到链表的最后一个节点
    struct Node* current = head;
    while (current->next != NULL) {
        current = current->next;
    }
    
    // 将最后一个节点的next指向新节点
    current->next = newNode;
    
    // 返回头节点
    return head;
}

在指定位置插入节点

cpp 复制代码
// 在指定位置插入节点
struct Node* insertAtPosition(struct Node* head, int data, int position) {
    // 如果位置是1,相当于在头部插入
    if (position == 1) {
        return insertAtBeginning(head, data);
    }
    
    // 创建新节点
    struct Node* newNode = createNode(data);
    
    // 找到要插入位置的前一个节点
    struct Node* current = head;
    for (int i = 1; i < position - 1 && current != NULL; i++) {
        current = current->next;
    }
    
    // 检查位置是否有效
    if (current == NULL) {
        printf("位置无效!\n");
        free(newNode);
        return head;
    }
    
    // 插入新节点
    newNode->next = current->next;
    current->next = newNode;
    
    return head;
}

删除节点

cpp 复制代码
// 删除指定值的第一个节点
struct Node* deleteNode(struct Node* head, int key) {
    // 如果链表为空,直接返回
    if (head == NULL) {
        return NULL;
    }
    
    // 如果头节点就是要删除的节点
    if (head->data == key) {
        struct Node* temp = head;
        head = head->next;
        free(temp);
        return head;
    }
    
    // 查找要删除的节点
    struct Node* current = head;
    while (current->next != NULL && current->next->data != key) {
        current = current->next;
    }
    
    // 如果找到了要删除的节点
    if (current->next != NULL) {
        struct Node* temp = current->next;
        current->next = temp->next;
        free(temp);
    }
    
    return head;
}

查找节点

cpp 复制代码
// 查找指定值的节点
struct Node* searchNode(struct Node* head, int key) {
    struct Node* current = head;
    
    // 遍历链表
    while (current != NULL) {
        if (current->data == key) {
            return current;  // 找到节点,返回指针
        }
        current = current->next;
    }
    
    return NULL;  // 未找到节点
}

打印链表

cpp 复制代码
// 打印链表的所有节点
void printList(struct Node* head) {
    struct Node* current = head;
    
    printf("链表内容: ");
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

释放链表

cpp 复制代码
// 释放链表的所有节点
void freeList(struct Node* head) {
    struct Node* current = head;
    struct Node* next;
    
    while (current != NULL) {
        next = current->next;  // 保存下一个节点
        free(current);         // 释放当前节点
        current = next;        // 移动到下一个节点
    }
}
cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

// 定义链表节点结构
struct Node {
    int data;
    struct Node* next;
};

// 创建新节点
struct Node* createNode(int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    if (newNode == NULL) {
        printf("内存分配失败!\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 在链表头部插入节点
struct Node* insertAtBeginning(struct Node* head, int data) {
    struct Node* newNode = createNode(data);
    newNode->next = head;
    return newNode;
}

// 在链表尾部插入节点
struct Node* insertAtEnd(struct Node* head, int data) {
    struct Node* newNode = createNode(data);
    
    if (head == NULL) {
        return newNode;
    }
    
    struct Node* current = head;
    while (current->next != NULL) {
        current = current->next;
    }
    
    current->next = newNode;
    return head;
}

// 在指定位置插入节点
struct Node* insertAtPosition(struct Node* head, int data, int position) {
    if (position == 1) {
        return insertAtBeginning(head, data);
    }
    
    struct Node* newNode = createNode(data);
    
    struct Node* current = head;
    for (int i = 1; i < position - 1 && current != NULL; i++) {
        current = current->next;
    }
    
    if (current == NULL) {
        printf("位置无效!\n");
        free(newNode);
        return head;
    }
    
    newNode->next = current->next;
    current->next = newNode;
    
    return head;
}

// 删除指定值的第一个节点
struct Node* deleteNode(struct Node* head, int key) {
    if (head == NULL) {
        return NULL;
    }
    
    if (head->data == key) {
        struct Node* temp = head;
        head = head->next;
        free(temp);
        return head;
    }
    
    struct Node* current = head;
    while (current->next != NULL && current->next->data != key) {
        current = current->next;
    }
    
    if (current->next != NULL) {
        struct Node* temp = current->next;
        current->next = temp->next;
        free(temp);
    }
    
    return head;
}

// 查找指定值的节点
struct Node* searchNode(struct Node* head, int key) {
    struct Node* current = head;
    
    while (current != NULL) {
        if (current->data == key) {
            return current;
        }
        current = current->next;
    }
    
    return NULL;
}

// 打印链表
void printList(struct Node* head) {
    struct Node* current = head;
    
    printf("链表内容: ");
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

// 释放链表
void freeList(struct Node* head) {
    struct Node* current = head;
    struct Node* next;
    
    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }
}

// 获取链表长度
int getLength(struct Node* head) {
    int count = 0;
    struct Node* current = head;
    
    while (current != NULL) {
        count++;
        current = current->next;
    }
    
    return count;
}

// 反转链表
struct Node* reverseList(struct Node* head) {
    struct Node* prev = NULL;
    struct Node* current = head;
    struct Node* next = NULL;
    
    while (current != NULL) {
        next = current->next;  // 保存下一个节点
        current->next = prev;  // 反转当前节点的指针
        prev = current;        // 移动prev指针
        current = next;        // 移动current指针
    }
    
    return prev;  // 新的头节点
}

int main() {
    struct Node* head = NULL;
    
    // 在链表尾部插入节点
    head = insertAtEnd(head, 10);
    head = insertAtEnd(head, 20);
    head = insertAtEnd(head, 30);
    
    printf("初始链表:\n");
    printList(head);
    
    // 在链表头部插入节点
    head = insertAtBeginning(head, 5);
    printf("\n在头部插入5后:\n");
    printList(head);
    
    // 在指定位置插入节点
    head = insertAtPosition(head, 15, 3);
    printf("\n在位置3插入15后:\n");
    printList(head);
    
    // 删除节点
    head = deleteNode(head, 20);
    printf("\n删除值为20的节点后:\n");
    printList(head);
    
    // 查找节点
    struct Node* found = searchNode(head, 15);
    if (found != NULL) {
        printf("\n找到值为15的节点\n");
    } else {
        printf("\n未找到值为15的节点\n");
    }
    
    // 获取链表长度
    printf("\n链表长度: %d\n", getLength(head));
    
    // 反转链表
    head = reverseList(head);
    printf("\n反转链表后:\n");
    printList(head);
    
    // 释放链表
    freeList(head);
    
    return 0;
}
相关推荐
AI科技星7 分钟前
张祥前统一场论宇宙大统一方程的求导验证
服务器·人工智能·科技·线性代数·算法·生活
Fuly10241 小时前
大模型剪枝(Pruning)技术简介
算法·机器学习·剪枝
Xの哲學1 小时前
Linux网卡注册流程深度解析: 从硬件探测到网络栈
linux·服务器·网络·算法·边缘计算
bubiyoushang8881 小时前
二维地质模型的表面重力值和重力异常计算
算法
仙俊红1 小时前
LeetCode322零钱兑换
算法
颖风船1 小时前
锂电池SOC估计的一种算法(改进无迹卡尔曼滤波)
python·算法·信号处理
551只玄猫2 小时前
KNN算法基础 机器学习基础1 python人工智能
人工智能·python·算法·机器学习·机器学习算法·knn·knn算法
charliejohn2 小时前
计算机考研 408 数据结构 哈夫曼
数据结构·考研·算法
POLITE32 小时前
Leetcode 41.缺失的第一个正数 JavaScript (Day 7)
javascript·算法·leetcode