当前位置: 首页 > ops >正文

《数据结构笔记四》双链表:创建,插入(头插、尾插、中间任意位置插入),删除,遍历,释放内存等核心操作。

双链表结构:数据域、前驱指针、后继指针;

结构体定义为:

typedef   struct  Node

{

        int data;

        struct  Node *prev;

        struct  Node  *next;

}Node;

步骤分为:

1. 定义节点结构体。

2. 编写创建节点的函数。

3. 编写头插法函数。

4. 编写尾插法函数。

5. 编写在任意位置插入的函数(比如指定位置索引)。

6. 编写删除节点的函数(按位置或按值)。

7. 编写遍历链表的函数。

8. 编写释放链表的函数。

9. 主函数中测试这些操作。

 代码实现:

#include <stdio.h>
#include <stdlib.h>// 定义双链表节点结构
typedef struct Node {int data;struct Node* prev;struct Node* next;
} Node;/*----------- 核心操作函数 -----------*/
// 创建新节点
Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (!newNode) {printf("Memory allocation failed!\n");exit(1);}newNode->data = data;newNode->prev = NULL;newNode->next = NULL;return newNode;
}// 头插法
void insertAtHead(Node** head, int data) {Node* newNode = createNode(data);if (*head != NULL) {newNode->next = *head;(*head)->prev = newNode;}*head = newNode;
}// 尾插法
void insertAtTail(Node** head, int data) {Node* newNode = createNode(data);if (*head == NULL) {*head = newNode;return;}Node* current = *head;while (current->next != NULL) {current = current->next;}current->next = newNode;newNode->prev = current;
}// 在指定位置插入(从0开始计数)
void insertAtPosition(Node** head, int pos, int data) {if (pos < 0) {printf("Invalid position!\n");return;}// 头插特殊情况处理if (pos == 0) {insertAtHead(head, data);return;}Node* newNode = createNode(data);Node* current = *head;// 定位到插入位置的前一个节点for (int i = 0; i < pos-1 && current != NULL; i++) {current = current->next;}if (current == NULL) {printf("Position exceeds list length!\n");free(newNode);return;}// 调整指针关系newNode->next = current->next;newNode->prev = current;if (current->next != NULL) {current->next->prev = newNode;}current->next = newNode;
}// 删除指定位置的节点
void deleteAtPosition(Node** head, int pos) {if (*head == NULL || pos < 0) {printf("List is empty or invalid position!\n");return;}Node* current = *head;// 定位到要删除的节点for (int i = 0; i < pos && current != NULL; i++) {current = current->next;}if (current == NULL) {printf("Position exceeds list length!\n");return;}// 调整前后节点的指针if (current->prev != NULL) {current->prev->next = current->next;} else {*head = current->next;  // 删除的是头节点}if (current->next != NULL) {current->next->prev = current->prev;}free(current);
}// 遍历打印链表(双向验证)
void printList(Node* head) {printf("Forward:  ");Node* current = head;while (current != NULL) {printf("%d -> ", current->data);current = current->next;}printf("NULL\n");// 反向遍历验证if (head == NULL) return;printf("Backward: ");current = head;while (current->next != NULL) {current = current->next;}while (current != NULL) {printf("%d -> ", current->data);current = current->prev;}printf("NULL\n\n");
}// 释放整个链表内存
void freeList(Node** head) {Node* current = *head;while (current != NULL) {Node* temp = current;current = current->next;free(temp);}*head = NULL;
}/*----------- 测试用例 -----------*/
int main() {Node* head = NULL;// 创建并操作链表insertAtTail(&head, 10);     // 尾插10insertAtHead(&head, 5);      // 头插5insertAtPosition(&head, 1, 7); // 在位置1插入7insertAtPosition(&head, 3, 20); // 在位置3插入20printList(head);  // 预期:5 -> 7 -> 10 -> 20deleteAtPosition(&head, 2);  // 删除位置2(值10)deleteAtPosition(&head, 0);  // 删除头节点(值5)printList(head);  // 预期:7 -> 20freeList(&head);  // 释放内存return 0;
}

代码说明:

  1. 完整功能实现

    • createNode:动态创建新节点

    • insertAtHead/insertAtTail:头插/尾插操作

    • insertAtPosition:支持任意位置插入

    • deleteAtPosition:支持任意位置删除

    • printList:双向遍历验证链表结构

    • freeList:完全释放内存避免泄漏

  2. 边界处理

    • 处理空链表插入/删除操作

    • 验证无效位置输入(负数、超长位置)

    • 双向指针调整确保链表完整性

  3. 内存管理

    • 每个动态分配的节点都会被正确释放

    • 删除操作后立即释放对应内存

  4. 验证方式

    • 正向/反向双重遍历验证指针正确性

    • 测试用例覆盖头/尾/中间操作场景

        运行该程序时,可以通过双向打印验证链表结构的正确性,同时所有内存操作都经过安全处理,避免常见的内存泄漏问题。

http://www.xdnf.cn/news/9309.html

相关文章:

  • 释放生产力潜能 AI-Hub智能数据中枢引领企业数字化转型
  • 粒子群优化(Particle Swarm Optimization, PSO)
  • 大模型(7)——向量模型(向量化存储)
  • Science综述:光电超构器件
  • Spring IoC(2)
  • 18、Python字符串全解析:Unicode支持、三种创建方式与长度计算实战
  • 【DeepSeek论文精读】12. DeepSeek-Prover-V2: 通过强化学习实现子目标分解的形式化数学推理
  • 【PhysUnits】14 二进制数的标准化表示(standardization.rs)
  • 【第1章 基础知识】1.6 事件处理
  • 嵌入式自学第二十九天(5.27)
  • 北京大学 | DeepSeek内部研讨资料:AI工具深度测评与选型指南,319页
  • 系统编程day05
  • 基于 STM32 的智慧农业温室控制系统设计与实现
  • 学习python day9
  • DeviceNET转EtherCAT协议转换网关解读
  • Qwen3内置提示词模板解读
  • 数据库大学实验一
  • 投影机三色光源和单色光源实拍对比:一场视觉体验的终极较量
  • 知识图谱系列(4):查询与推理技术
  • 第四十七篇-Tesla P40+Qwen3-30B-A3B部署与测试
  • 什么是PLM软件?离散制造业和流程制造业的主流PLM介绍、国产PLM应用案例
  • 5月27日星期二今日早报简报微语报早读
  • RuoYi前后端分离框架集成Jasypt实现配置信息加密
  • Kubernetes简介及常用命令
  • 高效大电流缓启动电路设计
  • Manus,AGI 要来临了吗?
  • 电子电路:欧姆定律和电流量子化有关系吗?
  • 深入剖析机器学习之波士顿房价案例
  • 易境通海外仓系统:如何提高仓库尾程派送环节效率?
  • 「Python教案」循环语句的使用