HW_Lib/lib/list/list.cpp

285 lines
6.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "list.h"
void list_init(List_t *list) {
list->head = NULL;
list->tail = NULL;
list->len = 0;
}
bool list_is_empty(List_t *list) {
return (list->head == NULL);
}
static struct List_Node_t *make_node(void *data) //把用户传递过来的数据打包为一个链表节点
{
struct List_Node_t *n;
n = (struct List_Node_t *) malloc(sizeof(struct List_Node_t));
assert(n != NULL);
n->next = NULL;
n->data = data;
return n;
}
void list_insert_at_head(List_t *list, void *data) //头插法
{
struct List_Node_t *n;
n = make_node(data);
if (list->head == NULL) { //如果是空链表
list->head = n;
list->tail = n;
} else { //如果不是非空链表
n->next = list->head;
list->head = n;
}
list->len++;
}
void list_insert_at_index(List_t *list, void *data, long index) //定插法
{
long i = 1; //从1开始算
struct List_Node_t *p, *n;
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++;
}
}
void list_insert_at_tail(List_t *list, void *data) //尾插法
{
struct List_Node_t *n;
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++;
}
//void list_insert(List_t *list, void *data) //默认采用尾插法
//{
//#if 0
// list_insert_at_tail(list, data);
//#else
// struct List_Node_t *n;
// 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
//}
void list_insert(List_t *list, void *data) {
struct List_Node_t *n;
n = make_node(data);
if (list->head == NULL) {
list->head = n;
list->tail = n;
} else {
list->tail->next = n;
list->tail = n;
}
list->len++;
}
void *list_delete(List_t *list, void *key, int (*compare)(const void *, const void *)) {
void *data;
struct List_Node_t *n, *t;
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
}
void *list_search(List_t *list, void *key, int (*compare)(const void *, const void *)) {
struct List_Node_t *n;
n = list->head;
while (n) {
if (!compare(n->data, key)) { //找到了,返回找到的数据
return n->data;
}
n = n->next;
}
return NULL; //找不到返回NULL
}
static struct List_Node_t *find_min_node(List_t *list,
int (*compare)(const void *, const void *)) {
struct List_Node_t *min, *n;
n = list->head;
min = list->head;
while (n) {
if (compare(min->data, n->data) > 0) {
min = n;
}
n = n->next;
}
return min;
}
static void delete_node(List_t *list, struct List_Node_t *key) {
struct List_Node_t *n;
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;
}
}
static void insert_node(List_t *list, struct List_Node_t *key) {
if (list->head == NULL) {
list->head = key;
list->tail = key;
} else {
list->tail->next = key;
list->tail = key;
}
}
void list_sort(List_t *list,
int (*compare)(const void *, const void *)) {
List_t tmp;
struct List_Node_t *n;
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;
}
void list_traverse(List_t *list, void (*handle)(void *)) {
struct List_Node_t *p;
p = list->head;
while (p) {
handle(p->data);
p = p->next;
}
}
void list_reverse(List_t *list) {
struct List_Node_t *pre = NULL, *next, *p = list->head;
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;
}
}
long list_get_lenth(List_t *list) {
return (list->len);
}
void *list_get_element(List_t *list, int idx) {
int i = 1;
struct List_Node_t *n;
n = list->head;
while (n && i < idx) {
i++;
n = n->next;
}
if (n) {
return n->data;
}
return NULL;
}
void list_destroy(List_t *list, void (*destroy)(void *)) {
list->len = 0;
struct List_Node_t *n, *t;
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,如此循环遍历链表,挨个删除,
}
}