HW_Lib/lib/list/list.cpp

285 lines
6.5 KiB
C++
Raw Normal View History

2024-06-21 05:25:01 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "list.h"
2024-06-21 07:21:42 +00:00
void list_init(List_t *list) {
2024-06-21 05:25:01 +00:00
list->head = NULL;
list->tail = NULL;
list->len = 0;
}
2024-06-21 07:21:42 +00:00
bool list_is_empty(List_t *list) {
2024-06-21 05:25:01 +00:00
return (list->head == NULL);
}
2024-06-21 07:21:42 +00:00
static struct List_Node_t *make_node(void *data) //把用户传递过来的数据打包为一个链表节点
2024-06-21 05:25:01 +00:00
{
2024-06-21 07:21:42 +00:00
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
2024-06-21 07:21:42 +00:00
n = (struct List_Node_t *) malloc(sizeof(struct List_Node_t));
2024-06-21 05:25:01 +00:00
assert(n != NULL);
n->next = NULL;
n->data = data;
return n;
}
2024-06-21 07:21:42 +00:00
void list_insert_at_head(List_t *list, void *data) //头插法
2024-06-21 05:25:01 +00:00
{
2024-06-21 07:21:42 +00:00
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
n = make_node(data);
if (list->head == NULL) { //如果是空链表
list->head = n;
list->tail = n;
} else { //如果不是非空链表
n->next = list->head;
list->head = n;
}
list->len++;
}
2024-06-21 07:21:42 +00:00
void list_insert_at_index(List_t *list, void *data, long index) //定插法
2024-06-21 05:25:01 +00:00
{
long i = 1; //从1开始算
2024-06-21 07:21:42 +00:00
struct List_Node_t *p, *n;
2024-06-21 05:25:01 +00:00
p = list->head;
while (p && i < index) {
p = p->next;
i++;
}
if (p) { //如果链表遍历完了计数i还没到index说明第index个节点不存在。
n = make_node(data);
n->next = p->next;
p->next = n;
list->len++;
}
}
2024-06-21 07:21:42 +00:00
void list_insert_at_tail(List_t *list, void *data) //尾插法
2024-06-21 05:25:01 +00:00
{
2024-06-21 07:21:42 +00:00
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
n = make_node(data);
if (list_is_empty(list)) { //如果是空链表
list->head = n;
list->tail = n;
} else { //如果不是非空链表
list->tail->next = n;
list->tail = n;
}
list->len++;
}
2024-06-21 07:21:42 +00:00
//void list_insert(List_t *list, void *data) //默认采用尾插法
2024-06-21 05:25:01 +00:00
//{
//#if 0
// list_insert_at_tail(list, data);
//#else
2024-06-21 07:21:42 +00:00
// struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
// n = make_node(data);
// if(list->head == NULL){
// list->head = n;
// list->tail = n;
// } else {
// list->tail->next = n;
// list->tail = n;
// }
// list->len++;
//#endif
//}
2024-06-21 07:21:42 +00:00
void list_insert(List_t *list, void *data) {
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
n = make_node(data);
if (list->head == NULL) {
list->head = n;
list->tail = n;
} else {
list->tail->next = n;
list->tail = n;
}
list->len++;
}
2024-06-21 07:21:42 +00:00
void *list_delete(List_t *list, void *key, int (*compare)(const void *, const void *)) {
2024-06-21 05:25:01 +00:00
void *data;
2024-06-21 07:21:42 +00:00
struct List_Node_t *n, *t;
2024-06-21 05:25:01 +00:00
n = list->head;
if (!compare(n->data, key)) { //如果要删除的节点为首节点
t = n;
data = n->data;
list->head = n->next;
free(t);
list->len--;
return data;
}
while (n->next != NULL) { //遍历查找符合条件的节点,删除之
if (compare(n->next->data, key) == 0) { //只删除第一个符合条件的节点。
t = n->next;
if (n->next == list->tail) {
list->tail = n;
}
n->next = n->next->next;
data = t->data;
free(t);
list->len--;
return data; //把删除的数据返回给用户,供用户后续的处理使用。
}
n = n->next;
}
return NULL; //没找到匹配的节点返回NULL
}
2024-06-21 07:21:42 +00:00
void *list_search(List_t *list, void *key, int (*compare)(const void *, const void *)) {
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
n = list->head;
while (n) {
if (!compare(n->data, key)) { //找到了,返回找到的数据
return n->data;
}
n = n->next;
}
return NULL; //找不到返回NULL
}
2024-06-21 07:21:42 +00:00
static struct List_Node_t *find_min_node(List_t *list,
2024-06-21 05:25:01 +00:00
int (*compare)(const void *, const void *)) {
2024-06-21 07:21:42 +00:00
struct List_Node_t *min, *n;
2024-06-21 05:25:01 +00:00
n = list->head;
min = list->head;
while (n) {
if (compare(min->data, n->data) > 0) {
min = n;
}
n = n->next;
}
return min;
}
2024-06-21 07:21:42 +00:00
static void delete_node(List_t *list, struct List_Node_t *key) {
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
n = list->head;
if (n == key) {
list->head = n->next;
return;
}
while (n->next) {
if (n->next == key) {
if (key == list->tail) {
list->tail = n;
}
n->next = n->next->next;
return;
}
n = n->next;
}
}
2024-06-21 07:21:42 +00:00
static void insert_node(List_t *list, struct List_Node_t *key) {
2024-06-21 05:25:01 +00:00
if (list->head == NULL) {
list->head = key;
list->tail = key;
} else {
list->tail->next = key;
list->tail = key;
}
}
2024-06-21 07:21:42 +00:00
void list_sort(List_t *list,
2024-06-21 05:25:01 +00:00
int (*compare)(const void *, const void *)) {
2024-06-21 07:21:42 +00:00
List_t tmp;
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
list_init(&tmp);
while (!list_is_empty(list)) {
n = find_min_node(list, compare);
delete_node(list, n);
n->next = NULL;
insert_node(&tmp, n);
}
list->head = tmp.head;
list->tail = tmp.tail;
}
2024-06-21 07:21:42 +00:00
void list_traverse(List_t *list, void (*handle)(void *)) {
struct List_Node_t *p;
2024-06-21 05:25:01 +00:00
p = list->head;
while (p) {
handle(p->data);
p = p->next;
}
}
2024-06-21 07:21:42 +00:00
void list_reverse(List_t *list) {
struct List_Node_t *pre = NULL, *next, *p = list->head;
2024-06-21 05:25:01 +00:00
list->tail = list->head; //tail指向head
while (p) {
next = p->next;
if (!next) { //当p->next为最后一个节点时让head指向p->next
list->head = p;
}
//记录当前节点为pre作为下一个节点的next.第一个节点为NULL初始化时已定义。
p->next = pre;
pre = p;
p = next;
}
}
2024-06-21 07:21:42 +00:00
long list_get_lenth(List_t *list) {
2024-06-21 05:25:01 +00:00
return (list->len);
}
2024-06-21 07:21:42 +00:00
void *list_get_element(List_t *list, int idx) {
2024-06-21 05:25:01 +00:00
int i = 1;
2024-06-21 07:21:42 +00:00
struct List_Node_t *n;
2024-06-21 05:25:01 +00:00
n = list->head;
while (n && i < idx) {
i++;
n = n->next;
}
if (n) {
return n->data;
}
return NULL;
}
2024-06-21 07:21:42 +00:00
void list_destroy(List_t *list, void (*destroy)(void *)) {
2024-06-21 05:25:01 +00:00
list->len = 0;
2024-06-21 07:21:42 +00:00
struct List_Node_t *n, *t;
2024-06-21 05:25:01 +00:00
n = list->head;
while (n) {
t = n->next; //t只起一个记录n->next的功能否则后面把n free掉之后就找不到n->next了。
if (destroy) { //传递用户自定义的数据处理函数为0时不执行
destroy(n->data); //使用用户提供的destroy函数来释放用户传递过来的数据。
}
free(n);
n = t; //把n free掉之后再把t给n相当于把n->next给n,如此循环遍历链表,挨个删除,
}
}