285 lines
6.5 KiB
C++
285 lines
6.5 KiB
C++
#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,如此循环遍历链表,挨个删除,
|
||
}
|
||
} |