建立动态链表

简介: 建立动态链表

一、引言


动态链表是数据结构中链表的一种实现方式,它不同于静态链表,在内存中通过动态分配和释放空间来存储数据元素。动态链表具有灵活性强、存储空间利用率高等优点,在程序设计中有着广泛的应用。本文将介绍如何建立动态链表,并给出相应的代码示例。


二、动态链表的基本结构


动态链表由若干个节点组成,每个节点包含两部分:数据域和指针域。数据域用于存储数据元素,指针域用于指向下一个节点。第一个节点称为头节点,它不包含数据元素,仅用于指向链表的第一个数据节点。最后一个节点的指针域为空(NULL),表示链表的结束。


三、建立动态链表的步骤 


定义节点结构体:首先,需要定义一个结构体来表示链表中的节点。该结构体应包含数据域和指针域。

c复制代码

  typedef struct Node { 
  int data; // 数据域 
  struct Node *next; // 指针域 
  } Node;

创建头节点:创建一个头节点,其数据域可以为任意值(通常不使用),指针域指向NULL。头节点的作用是方便对链表进行操作。

c复制代码

Node *head = (Node *)malloc(sizeof(Node)); // 创建头节点 
if (head == NULL) { 
exit(1); // 内存分配失败,退出程序 
} 
head->next = NULL; // 头节点的指针域指向NULL

插入节点:通过循环或递归的方式,向链表中插入新的节点。新节点的数据域存储要插入的数据,指针域指向当前节点的下一个节点,然后更新当前节点的指针域指向新节点。

c复制代码

void insert(Node *head, int value) { 
Node *newNode = (Node *)malloc(sizeof(Node)); // 创建新节点 
if (newNode == NULL) { 
exit(1); // 内存分配失败,退出程序 
} 
newNode->data = value; // 设置新节点的数据域 
newNode->next = head->next; // 将新节点插入到链表头部 
head->next = newNode; 
}

遍历链表:通过遍历链表,可以访问链表中的每个节点,并对其进行操作。遍历链表通常从头节点开始,沿着指针域依次访问每个节点,直到遇到指针域为NULL的节点为止。

c复制代码

void traverse(Node *head) { 
Node *current = head->next; // 从头节点的下一个节点开始遍历 
while (current != NULL) { 
printf("%d ", current->data); // 访问当前节点的数据域 
current = current->next; // 移动到下一个节点 
} 
printf("\n"); 
}

释放链表空间:当不再需要链表时,应释放链表所占用的内存空间。释放链表空间通常从头节点开始,依次释放每个节点的内存空间。

c复制代码

void freeList(Node *head) { 
Node *current = head; 
while (current != NULL) { 
Node *temp = current; 
current = current->next; 
free(temp); // 释放当前节点的内存空间 
} 
head = NULL; // 将头节点指针置为NULL,避免野指针 
}


四、代码示例


下面是一个完整的代码示例,展示了如何建立动态链表并进行插入、遍历和释放操作:

c复制代码

  #include <stdio.h> 
  #include <stdlib.h> 
  
  typedef struct Node { 
  int data; 
  struct Node *next; 
  } Node; 
  
  void insert(Node *head, int value); 
  void traverse(Node *head); 
  void freeList(Node *head); 
  
  int main() { 
  Node *head = (Node *)malloc(sizeof(Node)); 
  if (head == NULL) { 
  exit(1); 
  } 
  head->next = NULL; 
  
  // 插入节点 
  insert(head, 1); 
  insert(head, 2); 
  insert(head, 3); 
  
  // 遍历链表 
  traverse(head); 
  
  // 释放链表空间 
  freeList(head); 
  
  return 0; 
  } 
  
  void insert(Node *head, int value) { 
  Node *newNode = (Node *)malloc(sizeof(Node)); 
  if (newNode == NULL) { 
  exit(1); 
  } 
  newNode->data = value; 
  newNode->next = head->next; 
  head->next = newNode; 
  } 
  
  void traverse(Node *head


目录
相关文章
|
SQL 数据库 数据安全/隐私保护
Sql Server数据库Sa密码如何修改
Sql Server数据库Sa密码如何修改
1078 0
|
Python
NumPy 数学函数库详解
【8月更文第30天】NumPy(Numerical Python)是 Python 中用于科学计算的核心库之一,它提供了大量的高性能数学函数,并且是其他许多科学计算库的基础。本文将详细介绍 NumPy 中的数学函数,包括统计函数、线性代数函数以及傅里叶变换等功能。
312 0
如何调整 YOLOv3 的 NMS 参数以优化检测性能?
如何调整 YOLOv3 的 NMS 参数以优化检测性能?
|
11月前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
262 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
算法 Java C语言
【数据结构】后缀(逆波兰)表达式的计算以及中缀转后缀的方法
【数据结构】后缀(逆波兰)表达式的计算以及中缀转后缀的方法
2505 1
|
Kubernetes 监控 API
在K8S中,什么是 Minikube、Kubectl、Kubelet?
在K8S中,什么是 Minikube、Kubectl、Kubelet?
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
Clion+STM 32Warn : Failed to open device: LIBUSB_ERROR_NOT_SUPPORTED
Clion+STM 32Warn : Failed to open device: LIBUSB_ERROR_NOT_SUPPORTED
490 0
|
C++
Qt图片定时滚动播放器+透明过渡动画
解决:[QWidget::paintEngine: Should no longer be called QPainter::begin: Paint device returned engine == 0, type: 1] 需要在哪个控件上绘制,就要在哪个控件类中重写 paintEvent() ,所以本项目 需要使用自定义的MyQLabel继承QLabel
288 0
|
数据采集 机器学习/深度学习 Web App开发
提升爬虫OCR识别率:解决嘈杂验证码问题
使用OCR技术提升爬虫识别嘈杂验证码的准确率,结合Python代码示例展示了如何预处理图像、使用Tesseract和代理IP来规避反爬。通过灰度化、二值化增强验证码可读性,并利用代理IP保持爬虫稳定性。
513 0