C实现链表
简介
链表(Linked List)是一种常见的数据结构,用于存储一系列的元素。与数组不同,链表中的元素不必在内存中相邻地存储,而是通过指针来将它们连接起来。
链表由一系列 节点(Node) 组成,每个节点包含两部分:
- 数据域:可以存储任意类型的数据;
- 指针域:用于指向下一个节点或前一个节点。
链表的起始节点称为 头节点(Head) ,通常用一个指针指向它。链表的末尾节点通常指向一个 空值(NULL) ,表示链表的结束。
链表可以分为单向链表(单链表)和双向链表两种基本类型。
单向链表
单向链表(Single Linked List):每个节点只包含一个指针,指向下一个节点。单向链表只能从头节点开始沿着指针方向遍历链表,不能直接访问前一个节点。
双向链表
双向链表(Doubly Linked List):每个节点包含两个指针,一个指向前一个节点,一个指向后一个节点。双向链表可以从任意节点开始向前或向后遍历链表,可以直接访问前一个节点和后一个节点,因此在某些情况下操作更加灵活高效。
优点
- 动态性:链表的长度可以动态调整,可以根据需要灵活地插入或删除节点。
- 内存利用率:链表可以更好地利用内存,因为它不要求在内存中连续存储节点。
- 插入和删除操作效率高:相比数组,链表在任意位置插入或删除节点的操作效率更高,时间复杂度为 O(1)。
缺点
- 随机访问效率低:链表中的元素不是连续存储的,因此不能像数组那样通过下标随机访问元素,只能从头节点开始顺序访问。
- 额外的空间开销:每个节点需要额外的指针来指向下一个节点或前一个节点,可能会占用一定的额外内存空间。
- 不适合大量数据的操作:由于节点之间的指针关系,链表在处理大量数据时可能会产生额外的内存开销和时间开销。
尽管链表有一些缺点,但它仍然是一种常用的数据结构,特别适用于需要频繁插入和删除操作的场景,如实现栈、队列、哈希表等数据结构,以及某些算法问题的解决。
代码实现
单向链表
#include <stdio.h>
#include <stdlib.h>
// 链表节点的结构定义
typedef struct Node {
int val;
struct Node* next;
} Node;
// 创建一个新节点
Node* createNode(int val) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
newNode->val = val;
newNode->next = NULL;
return newNode;
}
// 释放一个节点的内存
void freeNode(Node* node) {
free(node);
}
int main() {
// 创建节点
Node* node1 = createNode(1);
Node* node2 = createNode(2);
Node* node3 = createNode(3);
// 将节点连接起来形成链表
node1->next = node2;
node2->next = node3;
// 遍历链表并打印节点的数据
Node* cur = node1;
while (cur != NULL) {
printf("%d ", cur->val);
cur = cur->next;
}
printf("\n");
// 释放节点的内存
Node* tmp;
cur = node1;
while(cur) {
tmp = cur;
cur = cur->next;
freeNode(tmp);
}
return 0;
}
双向链表
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int val;
struct Node* prev;
struct Node* next;
} Node;
Node* createNode(int val) {
Node* node = (Node*)malloc(sizeof(Node));
node->val = val;
node->prev = NULL;
node->next = NULL;
return node;
}
void freeNode(Node* node) {
free(node);
}
int main() {
Node* node1 = createNode(1);
Node* node2 = createNode(2);
Node* node3 = createNode(3);
node1->next = node2;
node2->prev = node1;
node2->next = node3;
node3->prev = node2;
Node* cur = node1;
while(cur) {
printf("%d ", cur->val);
cur = cur->next;
}
cur = node3;
while(cur) {
printf("%d ", cur->val);
cur = cur->prev;
}
Node* tmp;
cur = node1;
while (cur) {
tmp = cur;
cur = cur->next;
freeNode(tmp);
}
return 0;
}

浙公网安备 33010602011771号