链表的相关操作
#pragma once
// 编程的接口(API)
// *.h 文件中一般会放:类型的定义,函数的声明,全局变量
#include <stdbool.h>
typedef struct node {
int val;
struct node* next;
} Node;
typedef struct {
Node* head;
Node* tail;
int size;
} List;
List* create_list();
void destroy_list(List* list);
void add_before_head(List* list, int val);
void add_behind_tail(List* list, int val);
void add_node(List* list, int idx, int val);
bool delete_node(List* list, int val);
int find_by_index(List* list, int idx);
Node* search(List* list, int val);
#include "List.h"
#include <stdlib.h>
#include <stdio.h>
// 创建空的链表
List* create_list() {
return calloc(1, sizeof(List));
}
// 释放资源
void destroy_list(List* list) {
if (list == NULL) return;
// 先释放所有Node
Node* curr = list->head;
while (curr != NULL) {
Node* next = curr->next;
free(curr);
curr = next;
}
// 释放List结构体
free(list);
}
// 头插法
void add_before_head(List* list, int val) {
// 创建结点
Node* newNode = malloc(sizeof(Node));
if (newNode == NULL) {
printf("malloc failed in add_before_head\n");
exit(1);
}
// 初始化结点
newNode->val = val;
newNode->next = list->head;
// 更新List的信息
list->head = newNode;
if (list->size == 0) {
list->tail = newNode;
}
list->size++;
}
// 尾插法
void add_behind_tail(List* list, int val) {
// 创建结点
Node* newNode = malloc(sizeof(Node));
if (newNode == NULL) {
printf("malloc failed in add_behind_tail\n");
exit(1);
}
// 初始化结点
newNode->val = val;
newNode->next = NULL;
// 链接
if (list->size != 0) {
list->tail->next = newNode;
}
// 更新List信息
if (list->size == 0) {
list->head = newNode;
}
list->tail = newNode;
list->size++;
}
void add_node(List* list, int idx, int val) {
// 1. 参数校验
if (idx < 0 || idx > list->size) {
printf("Illegal argument: idx = %d\n", idx);
return;
}
// 头插
if (idx == 0) {
add_before_head(list, val);
return;
}
// 尾插
if (idx == list->size) {
add_behind_tail(list, val);
return;
}
// 在中间插入
// 1. 创建结点
Node* newNode = malloc(sizeof(Node));
if (newNode == NULL) {
printf("malloc failed in add\n");
exit(1);
}
// 2. 初始化结点
newNode->val = val;
// 3. 找索引为 idx-1 的结点
Node* curr = list->head;
//循环不变式:curr指向结点的索引为i
for (int i = 0; i < idx - 1; i++) {
curr = curr->next;
}
newNode->next = curr->next;
curr->next = newNode;
list->size++;
}
// 根据索引查找值
int find_by_index(List* list, int idx) {
// 1. 参数校验
if (idx < 0 || idx >= list->size) {
printf("Illegal argument: idx = %d\n", idx);
return -1;
}
// 2. 查找索引为 idx 的元素
Node* curr = list->head;
for (int i = 0; i < idx; i++) {
curr = curr->next;
}
return curr->val;
}
// 查找与特定值相等的结点
Node* search(List* list, int val) {
Node* curr = list->head;
while (curr != NULL) {
if (curr->val == val) {
return curr;
}
// 移动到下一个结点
curr = curr->next;
}
return NULL;
}
// 删除第一个值等于val的结点
bool delete_node(List* list, int val) {
Node* prev = NULL;
Node* curr = list->head;
while (curr != NULL) {
if (curr->val == val) {
// 删除curr结点
if (prev == NULL) {
// 修改链表信息
list->head = curr->next;
if (list->size == 1) {
list->tail = NULL;
}
list->size--;
free(curr);
}
else {
// 修改链表信息
prev->next = curr->next;
if (curr->next == NULL) {
list->tail = prev;
}
list->size--;
free(curr);
}
return true;
}
// 往后移
prev = curr;
curr = curr->next;
}
return false;
}