1.单链表的定义
线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。为了建立数据元素之间的线性关系,对每个链表结点,除存放元素自身的信息之外,还需要存放一个指向其后继的指针。
2.单链表的基本操作
2.1单链表的建立
2.1.1头插法建立单链表
该方法从一个空表开始,生成新结点,并将读取到的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头,即头结点之后。
// 头插法建立单链表
Node* createListHead(int arr[], int n) {
Node* head = NULL;
for (int i = 0; i <n; i++) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = arr[i];
newNode->next = head;
head = newNode;
}
return head;
}
2..1.2尾插法建立单链表
该方法将新结点插入到当前链表的表尾,为此必须增加一个尾指针 ,使其始终指向当前链表的尾结点。
// 尾插法建立单链表
Node* createListTail(int arr[], int n) {
Node* head = NULL;
Node* tail = NULL;
for (int i = 0; i < n; i++) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = arr[i];
newNode->next = NULL;
if (head == NULL) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
}
return head;
}
2.2.删除单链表节点
删除结点操作是将单链表的第i个结点删除。先检查删除位置的合法性,然后查找表中第i-1个结点,即被删结点的前驱,再删除第i个结点。
// 删除单链表节点
void deleteByIndex(Node** head, int index) {
if (*head == NULL) {
return;
}
Node* current = *head;//如果要删除的是头结点
if (index == 0) {
*head = current->next;
free(current);
return;
}
for (int i = 0; current != NULL && i < index - 1; i++) {//删除的不是头结点
current = current->next;
}
if (current == NULL || current->next == NULL) {
return;
}
Node* temp = current->next;
current->next = temp->next;
free(temp);
}
2.3.插入单链表节点
插入结点操作将值为x的新结点插入到单链表的第i个位置。先检查插入位置的合法性,然后找到待插入位置的前驱,即第i-1个结点,再在其后插入。
// 单链表中插入节点
void insertByIndex(Node** head, int index, int value) {
//创建一个新节点
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = NULL;
if (*head == NULL || index == 0) {
newNode->next = *head;
*head = newNode;
return;
}
Node* current = *head;
for (int i = 0; current != NULL && i < index - 1; i++) {
current = current->next;
}
if (current == NULL) {
free(newNode);
return;
}
newNode->next = current->next;
current->next = newNode;
}
2.4.查找到单链表节点
2.4.1按值查找
从单链表的第一个结点开始,从前往后依次比较表中各结点的数据域,若某结点的 data 域等于给定值e,则返回该结点的指针;若整个单链表中没有这样的结点,则返回NULL。
//按值查找点
Node* findByValue(Node* head, int value) {
Node* current = head;
while (current != NULL) {
if (current->data == value) {
return current;
}
current = current->next;
}
return NULL;
}
2.4.2按位查找
从单链表的第一个结点开始,沿着 next域从前往后依次搜索,直到找到第i个结点为止,
则返回该结点的指针;若i小于单链表的表长,则返回NULL。
// 按位查找
Node* findByIndex(Node* head, int index) {
Node* current = head;
for (int i = 0; current != NULL && i < index; i++) {
current = current->next;
}
return current;
2.5.main主函数
int main() {
int n;
printf("请输入节点数量: ");
scanf("%d", &n);
int arr[n];
printf("请输入节点数据: ");
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// 创建单链表
Node* head = createListTail(arr, n);
printf("初始链表: ");
printList(head);
// 插入和删除测试
int deleteIndex, insertIndex, findIndex;
printf("请输入要删除的位置(0为头节点): ");
scanf("%d", &deleteIndex);
deleteByIndex(&head, deleteIndex);
printf("删除位置 %d 后的链表: ", deleteIndex);
printList(head);
printf("请输入要插入的位置(0为头节点): ");
scanf("%d", &insertIndex);
printf("请输入要插入的值: ");
int insertValue;
scanf("%d", &insertValue);
insertByIndex(&head, insertIndex, insertValue);
printf("插入位置 %d 后的链表: ", insertIndex);
printList(head);
printf("请输入要查找的位置(0为头节点): ");
scanf("%d", &findIndex);
Node* foundNode = findByIndex(head, findIndex);
if (foundNode) {
printf("找到索引 %d 的节点: %d\n", findIndex, foundNode->data);
} else {
printf("未找到索引 %d 的节点\n", findIndex);
}
// 按值查找
printf("请输入要查找的值: ");
int findValue;
scanf("%d", &findValue);
foundNode = findByValue(head, findValue);
if (foundNode) {
printf("找到值 %d 的节点: %d\n", findValue, foundNode->data);
} else {
printf("未找到值 %d 的节点\n", findValue);
}
// 清理链表
while (head != NULL) {
Node* temp = head;
head = head->next;
free(temp);
}
return 0;
}
3.运行结果
3.1单链表的建立
3.2删除节点
3.3插入节点
3.4查找节点
3.4.1按值查找
3.4.2按位查找
4.完整代码
#include <stdio.h>
#include <stdlib.h>
// 定义单链表节点结构体
typedef struct Node {
int data;
struct Node* next;
} Node;
// 头插法建立单链表
Node* createListHead(int arr[], int n) {
Node* head = NULL;
for (int i = n - 1; i >= 0; i--) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = arr[i];
newNode->next = head;
head = newNode;
}
return head;
}
// 尾插法建立单链表
Node* createListTail(int arr[], int n) {
Node* head = NULL;
Node* tail = NULL;
for (int i = 0; i < n; i++) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = arr[i];
newNode->next = NULL;
if (head == NULL) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
}
return head;
}
// 打印单链表
void printList(Node* head) {
Node* current = head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
// 删除单链表节点
void deleteByIndex(Node** head, int index) {
if (*head == NULL) {
return;
}
Node* current = *head;//如果要删除的是头结点
if (index == 0) {
*head = current->next;
free(current);
return;
}
for (int i = 0; current != NULL && i < index - 1; i++) {//删除的不是头结点
current = current->next;
}
if (current == NULL || current->next == NULL) {
return;
}
Node* temp = current->next;
current->next = temp->next;
free(temp);
}
// 单链表中插入节点
void insertByIndex(Node** head, int index, int value) {
//创建一个新节点
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = NULL;
if (*head == NULL || index == 0) {
newNode->next = *head;
*head = newNode;
return;
}
Node* current = *head;
for (int i = 0; current != NULL && i < index - 1; i++) {
current = current->next;
}
if (current == NULL) {
free(newNode);
return;
}
newNode->next = current->next;
current->next = newNode;
}
// 按位查找
Node* findByIndex(Node* head, int index) {
Node* current = head;
for (int i = 0; current != NULL && i < index; i++) {
current = current->next;
}
return current;
}
//按值查找点
Node* findByValue(Node* head, int value) {
Node* current = head;
while (current != NULL) {
if (current->data == value) {
return current;
}
current = current->next;
}
return NULL;
}
int main() {
int n;
printf("请输入节点数量: ");
scanf("%d", &n);
int arr[n];
printf("请输入节点数据: ");
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// 创建单链表
Node* head = createListTail(arr, n);
printf("初始链表: ");
printList(head);
// 插入和删除测试
int deleteIndex, insertIndex, findIndex;
printf("请输入要删除的位置(0为头节点): ");
scanf("%d", &deleteIndex);
deleteByIndex(&head, deleteIndex);
printf("删除位置 %d 后的链表: ", deleteIndex);
printList(head);
printf("请输入要插入的位置(0为头节点): ");
scanf("%d", &insertIndex);
printf("请输入要插入的值: ");
int insertValue;
scanf("%d", &insertValue);
insertByIndex(&head, insertIndex, insertValue);
printf("插入位置 %d 后的链表: ", insertIndex);
printList(head);
printf("请输入要查找的位置(0为头节点): ");
scanf("%d", &findIndex);
Node* foundNode = findByIndex(head, findIndex);
if (foundNode) {
printf("找到索引 %d 的节点: %d\n", findIndex, foundNode->data);
} else {
printf("未找到索引 %d 的节点\n", findIndex);
}
// 按值查找
printf("请输入要查找的值: ");
int findValue;
scanf("%d", &findValue);
foundNode = findByValue(head, findValue);
if (foundNode) {
printf("找到值 %d 的节点: %d\n", findValue, foundNode->data);
} else {
printf("未找到值 %d 的节点\n", findValue);
}
// 清理链表
while (head != NULL) {
Node* temp = head;
head = head->next;
free(temp);
}
return 0;
}