一、链表
链表(Linked List)是一种常见的数据结构,它由一系列节点(Node)组成,每个节点包含数据域和指向下一个节点的指针域。链表的优点是插入和删除操作在已知位置的情况下时间复杂度为O(1),而不像数组需要O(n)的时间复杂度来移动元素。链表的缺点是随机访问元素时需要O(n)的时间。
二、单链表
在单链表中,每个节点包含数据域和一个指向下一个节点的指针。单链表的基本结构如下:
struct Node {
int data;
struct Node* next;
};
三、单链表的建立
建立单链表通常包括创建头节点(head)并逐个添加新节点。
// 创建一个新节点
struct Node* createNode(int data)
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
代码详解:
函数定义:
struct Node* createNode(int data)
struct Node*
:这是函数的返回类型,表示该函数返回一个指向Node
结构体的指针。createNode
:这是函数的名字。(int data)
:这是函数的参数列表,这里只有一个参数data
,类型为int
,表示新节点中要存储的数据。
内存分配:
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
malloc(sizeof(struct Node))
:使用malloc
函数动态分配一块内存,大小为struct Node
结构体的大小。malloc
返回一个指向这块内存的指针,但是它的类型是void*
。(struct Node*)
:将malloc
返回的void*
类型指针强制转换为struct Node*
类型。struct Node* newNode
:定义一个指向Node
结构体的指针变量newNode
,并将上一步得到的指针赋值给它。
初始化节点
设置节点的数据域
newNode->data = data;
-
newNode->data
:通过指针访问Node
结构体中的data
成员。= data
:将函数参数data
的值赋给新节点的data
成员。
设置节点的指针域
newNode->next = NULL;
newNode->next
:通过指针访问Node
结构体中的next
成员。= NULL
:将next
指针设置为NULL
,表示这个节点暂时没有连接到任何其他节点。
返回新节点
return newNode;
return newNode
:返回指向新创建的 Node
结构体的指针。
总结:该函数的作用是创建一个新的节点并初始化其数据域和指针域,然后返回这个节点的指针。
//初始化链表
struct Node* createLinkedList(int arr[], int n)
{
if (n == 0) return NULL;
struct Node* head = createNode(arr[0]);
struct Node* current = head;
for (int i = 1; i < n; i++)
{
current->next = createNode(arr[i]);
current = current->next;
}
return head;
}
代码详解:
函数定义:
struct Node* createLinkedList(int arr[], int n)
struct Node*
:这是函数的返回类型,表示该函数返回一个指向Node
结构体的指针。createLinkedList
:这是函数的名字。(int arr[], int n)
:这是函数的参数列表,arr
是一个整数数组,表示要存储在链表中的数据,n
是数组的长度。
处理空数组:
if (n == 0) return NULL;
如果数组长度为 0,直接返回 NULL
,表示创建一个空链表。
创建头节点:
struct Node* head = createNode(arr[0]);
调用 createNode
函数,使用数组的第一个元素 arr[0]
创建一个新节点,并将其指针赋给 head
。head
是链表的头节点。
创建其他节点:
初始化当前节点指针
struct Node* current = head;
定义一个指针 current
,并将其指向链表的头节点 head
。current
将用于遍历和构建链表。
创建链表的其余节点
for (int i = 1; i < n; i++) {
current->next = createNode(arr[i]);
current = current->next;
}
- 使用
for
循环从1
开始遍历数组,直到n-1
。 - 在每次循环中:
current->next = createNode(arr[i])
:调用createNode
函数,使用数组的当前元素arr[i]
创建一个新节点,并将新节点的指针赋给当前节点的next
指针。current = current->next
:将current
更新为新创建的节点,以便在下一次循环中继续构建链表。
返回链表的头节点:
return head;
函数最后返回链表的头节点 head
,这是整个链表的入口点。
总结:该函数的作用是根据给定的数组创建一个单链表。它首先检查数组是否为空,如果是,则返回 NULL
。否则,它创建链表的头节点,然后遍历数组,逐个创建新节点并将它们连接起来。最后,返回链表的头节点。这段代码展示了如何动态地构建链表并将数组中的数据转换成链表结构。
单链表建立完整代码
#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));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 初始化链表
struct Node* createLinkedList(int arr[], int n) {
if (n == 0) return NULL;
struct Node* head = createNode(arr[0]);
struct Node* current = head;
for (int i = 1; i < n; i++) {
current->next = createNode(arr[i]);
current = current->next;
}
return head;
}
四、单链表的输出
void printLinkedList(struct Node* head)
{
struct Node* current = head;
while (current != NULL)
{
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
}
- 从头节点开始,用一个指针
current
指向链表的头节点。 - 进入
while
循环,只要current
不为NULL
,就打印当前节点的数据。 - 将
current
更新为下一个节点,继续遍历。 - 循环结束后,打印
NULL
,表示链表的结束。