链式存储结构通过使用指针将分散的存储单元链接起来,每个元素由数据部分和指针部分组成。
链式表的定义和特点
链式表的每个节点包含两个部分:
- 数据域:存储数据元素。
- 指针域:存储下一个节点的内存地址。
链式表的头指针指向第一个节点,最后一个节点的指针域为NULL,表示链表结束。链式表的特点是插入和删除操作比较方便,不需要移动大量元素,但随机访问效率较低。
示例代码:链式表的实现及取值操作(C语言)
c
#include <stdio.h>
#include <stdlib.h>
// 定义链式表节点结构
typedef struct Node {
int data; // 数据域
struct Node *next; // 指针域,指向下一个节点
} Node;
// 创建新节点
Node* create_node(int value) {
Node *new_node = (Node*)malloc(sizeof(Node)); // 分配内存
if (new_node == NULL) {
printf("内存分配失败\n");
exit(1); // 分配失败则退出程序
}
new_node->data = value; // 设置节点数据
new_node->next = NULL; // 初始化指针为NULL
return new_node; // 返回新节点的指针
}
// 在链表尾部插入节点
void append(Node **head, int value) {
Node *new_node = create_node(value); // 创建新节点
if (*head == NULL) { // 如果链表为空
*head = new_node; // 新节点成为头节点
return;
}
Node *current = *head; // 从头节点开始遍历
while (current->next != NULL) { // 找到链表的最后一个节点
current = current->next;
}
current->next = new_node; // 将新节点链接到链表末尾
}
// 获取指定位置的元素值
int get_value(Node *head, int pos, int *value) {
if (head == NULL) { // 如果链表为空
printf("链表为空\n");
return 0; // 返回0表示失败
}
Node *current = head;
int index = 0;
while (current != NULL) { // 遍历链表
if (index == pos) { // 找到指定位置
*value = current->data; // 获取节点数据
return 1; // 返回1表示成功
}
current = current->next; // 移动到下一个节点
index++;
}
printf("位置超出范围\n"); // 如果遍历完链表也没找到指定位置
return 0; // 返回0表示失败
}
// 打印链表
void print_list(Node *head) {
Node *current = head;
printf("链表内容:");
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
// 释放链表内存
void free_list(Node *head) {
Node *current = head;
while (current != NULL) {
Node *temp = current;
current = current->next;
free(temp);
}
}
int main() {
Node *head = NULL; // 初始化链表为空
append(&head, 10); // 向链表尾部添加元素10
append(&head, 20); // 向链表尾部添加元素20
append(&head, 30); // 向链表尾部添加元素30
print_list(head); // 打印链表内容
int value;
if (get_value(head, 1, &value)) { // 获取索引1的元素值
printf("索引1的元素值:%d\n", value);
}
free_list(head); // 释放链表内存
return 0;
}
代码各模块注释
定义链式表节点结构
c
typedef struct Node {
int data; // 数据域
struct Node *next; // 指针域,指向下一个节点
} Node;
- 定义了一个名为
Node
的结构体类型,表示链式表的节点。 int data;
用于存储节点的数据。struct Node *next;
是一个指向Node
类型的指针,用于存储下一个节点的内存地址。
创建新节点
c
Node* create_node(int value) {
Node *new_node = (Node*)malloc(sizeof(Node)); // 分配内存
if (new_node == NULL) {
printf("内存分配失败\n");
exit(1); // 分配失败则退出程序
}
new_node->data = value; // 设置节点数据
new_node->next = NULL; // 初始化指针为NULL
return new_node; // 返回新节点的指针
}
Node *new_node = (Node*)malloc(sizeof(Node));
使用malloc
函数动态分配内存,为新节点分配大小为sizeof(Node)
的内存空间。if (new_node == NULL) { ... }
检查内存分配是否成功。如果失败,打印错误信息并退出程序。new_node->data = value;
将传入的value
值赋给新节点的数据域。new_node->next = NULL;
将新节点的指针域初始化为NULL
,表示该节点目前没有指向下一个节点。return new_node;
返回新创建的节点的指针。
在链表尾部插入节点
c
void append(Node **head, int value) {
Node *new_node = create_node(value); // 创建新节点
if (*head == NULL) { // 如果链表为空
*head = new_node; // 新节点成为头节点
return;
}
Node *current = *head; // 从头节点开始遍历
while (current->next != NULL) { // 找到链表的最后一个节点
current = current->next;
}
current->next = new_node; // 将新节点链接到链表末尾
}
Node *new_node = create_node(value);
调用create_node
函数创建一个新节点。if (*head == NULL) { ... }
检查链表是否为空。如果链表为空(头指针为NULL
),将新节点设置为头节点。Node *current = *head;
定义一个指针current
,初始化为链表的头节点,用于遍历链表。while (current->next != NULL) { ... }
遍历链表,直到找到最后一个节点(其next
指针为NULL
)。current->next = new_node;
将最后一个节点的next
指针指向新节点,将新节点添加到链表末尾。
获取指定位置的元素值
c
int get_value(Node *head, int pos, int *value) {
if (head == NULL) { // 如果链表为空
printf("链表为空\n");
return 0; // 返回0表示失败
}
Node *current = head;
int index = 0;
while (current != NULL) { // 遍历链表
if (index == pos) { // 找到指定位置
*value = current->data; // 获取节点数据
return 1; // 返回1表示成功
}
current = current->next; // 移动到下一个节点
index++;
}
printf("位置超出范围\n"); // 如果遍历完链表也没找到指定位置
return 0; // 返回0表示失败
}
if (head == NULL) { ... }
检查链表是否为空。如果为空,打印错误信息并返回0表示失败。Node *current = head;
定义一个指针current
,初始化为链表的头节点,用于遍历链表。int index = 0;
用于记录当前遍历到的节点位置。while (current != NULL) { ... }
遍历链表,直到current
为NULL
(链表结束)。if (index == pos) { ... }
检查当前节点的位置是否为目标位置pos
。如果是,将当前节点的数据赋值给*value
,并返回1表示成功。current = current->next;
移动current
指针到下一个节点。index++;
增加位置计数器。- 如果遍历完整个链表都没有找到目标位置,打印错误信息并返回0表示失败。
打印链表
c
void print_list(Node *head) {
Node *current = head;
printf("链表内容:");
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
Node *current = head;
定义一个指针current
,初始化为链表的头节点,用于遍历链表。printf("链表内容:");
打印提示信息。while (current != NULL) { ... }
遍历链表,直到current
为NULL
。printf("%d ", current->data);
打印当前节点的数据。current = current->next;
移动current
指针到下一个节点。printf("\n");
打印换行符,换行。
释放链表内存
c
void free_list(Node *head) {
Node *current = head;
while (current != NULL) {
Node *temp = current;
current = current->next;
free(temp);
}
}
Node *current = head;
定义一个指针current
,初始化为链表的头节点,用于遍历链表。while (current != NULL) { ... }
遍历链表,直到current
为NULL
。Node *temp = current;
保存当前节点的指针到temp
。current = current->next;
移动current
指针到下一个节点。free(temp);
释放temp
指向的节点内存。
主函数
c
int main() {
Node *head = NULL; // 初始化链表为空
append(&head, 10); // 向链表尾部添加元素10
append(&head, 20); // 向链表尾部添加元素20
append(&head, 30); // 向链表尾部添加元素30
print_list(head); // 打印链表内容
int value;
if (get_value(head, 1, &value)) { // 获取索引1的元素值
printf("索引1的元素值:%d\n", value);
}
free_list(head); // 释放链表内存
return 0;
}
Node *head = NULL;
声明一个指向Node
的指针head
,并初始化为NULL
,表示链表为空。append(&head, 10);
调用append
函数向链表尾部添加元素10。append(&head, 20);
向链表尾部添加元素20。append(&head, 30);
向链表尾部添加元素30。print_list(head);
调用print_list
函数打印链表的内容。int value;
声明一个整型变量value
,用于存储获取的元素值。if (get_value(head, 1, &value)) { ... }
调用get_value
函数尝试获取索引1处的元素值。如果成功,打印该值。free_list(head);
调用free_list
函数释放链表占用的内存。return 0;
返回0,表示程序正常结束。