提交 9c984848 authored 作者: zhoush's avatar zhoush

改为双向链表, 使用哑头

上级 cd16bd7a
流水线 #1899 已失败 于阶段
...@@ -3,146 +3,112 @@ ...@@ -3,146 +3,112 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
typedef enum typedef enum { TRUE = 1, FALSE = 0 } BOOL;
{
TRUE = 1,
FALSE = 0
} BOOL;
// ================> SOURCE CODE BELOW <================ // ================> SOURCE CODE BELOW <================
AWList* AWList_init(AWList* list) AWList* AWList_init(AWList* list) {
{ if (list == NULL) {
if (list == NULL) list = calloc(1, sizeof(AWList));
{
list = calloc(1, sizeof(AWList)); list->free_me = TRUE;
} else {
list->free_me = TRUE; list->free_me = FALSE;
} }
else
{ list->head = calloc(1, sizeof(AWNode));
list->free_me = FALSE; list->tail = list->head;
} list->iter = list->head;
list->cnt = 0;
list->head = NULL; return list;
list->tail = NULL;
list->curr = NULL;
list->cnt = 0;
return list;
} }
void AWList_destroy(AWList* list) void AWList_destroy(AWList* list) {
{ AWList_clear(list);
if (list)
{ free(list->head);
for (; list->head; AWList_delete_node(list, list->head)) if (list->free_me) { free(list); }
;
if (list->free_me == TRUE)
{
free(list);
list = NULL;
}
}
} }
void AWList_add_head(AWList* list, void* data, void (*delete_func)(void*)) void AWList_clear(AWList* list) {
{ if (!list) { return; }
AWNode* node = (AWNode*)malloc(sizeof(AWNode)); for (; list->tail != list->head; AWList_delete_node(list, list->tail))
node->data = data; ;
node->delete_func = delete_func;
if (list->head == NULL)
{
node->next = NULL;
list->tail = node;
}
else
{
node->next = list->head;
}
list->curr = list->head = node;
list->cnt += 1;
} }
void AWList_add_tail(AWList* list, void* data, void (*delete_func)(void*)) AWNode* AWNode_init(void* data, void (*delete_func)(void*)) {
{ AWNode* node = malloc(sizeof(AWNode));
AWNode* node = (AWNode*)malloc(sizeof(AWNode)); node->data = data;
node->data = data; node->delete_func = delete_func;
node->next = NULL;
node->delete_func = delete_func; node->prev = NULL;
node->next = NULL;
if (list->head == NULL)
{ return node;
list->curr = list->head = node;
}
else
{
list->tail->next = node;
}
list->tail = node;
list->cnt += 1;
} }
void AWList_delete_node(AWList* list, AWNode* node) void AWNode_destroy(AWNode* node) {
{ if (node->next) { node->next->prev = node->prev; }
if (list->head == NULL || node == NULL || node->delete_func == NULL) return; node->prev->next = node->next;
if (node && node->delete_func) { node->delete_func(node->data); }
if (list->head == node) free(node);
{
list->curr = list->head = list->head->next;
}
else
{
AWNode* tmp = list->head;
for (; tmp->next && tmp->next != node; tmp = tmp->next)
{
}
if (tmp->next == node)
tmp->next = node->next;
else
return;
}
node->delete_func(node->data);
free(node);
node = NULL;
list->cnt -= 1;
} }
void AWList_clear(AWList *list) void AWList_delete_node(AWList* list, AWNode* node) {
{ if (!list || !list->head || !node) return;
int freeme = list->free_me;
list->free_me = FALSE;
AWList_destroy(list); if (list->tail == node) { list->tail = node->prev; }
if (list->iter == node) { list->iter = node->prev; }
list->free_me = freeme; AWNode_destroy(node);
list->cnt -= 1;
} }
AWNode *AWList_find_node(AWList* list, void* data, int (*cmp_callback)(void*, void*)) void AWList_add_head(AWList* list, void* data, void (*delete_func)(void*)) {
{ if (!list || !list->head) return;
AWNode *node;
AWList_for_each(node, list) AWNode* node = AWNode_init(data, delete_func);
{ AWNode* dummy = list->head;
if (cmp_callback(node->data, data) == 0)
return node; node->prev = dummy;
} node->next = dummy->next;
dummy->next->prev = node;
dummy->next = node;
return NULL; list->iter = node;
list->cnt += 1;
} }
AWNode* AWList_iterator(AWList* list) void AWList_add_tail(AWList* list, void* data, void (*delete_func)(void*)) {
{ AWNode* node = AWNode_init(data, delete_func);
if (list->curr)
{ node->prev = list->tail;
AWNode* curr = list->curr; node->next = NULL;
list->curr = list->curr->next;
return curr; list->tail->next = node;
} list->tail = node;
else
return NULL; list->cnt += 1;
}
AWNode* AWList_find_node(AWList* list,
void* data,
int (*cmp_callback)(void*, void*)) {
AWNode* node;
AWList_for_each(node, list) {
if (cmp_callback(node->data, data) == 0) return node;
}
return NULL;
}
AWNode* AWList_iterator(AWList* list) {
if (!list || list->iter == list->tail->next) return NULL;
if (list->iter == list->head) list->iter = list->head->next;
AWNode* iter = list->iter;
list->iter = list->iter->next;
return iter;
} }
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
* @param data data of node * @param data data of node
* @param delete_func function to free data * @param delete_func function to free data
*/ */
typedef struct _node typedef struct _node {
{ struct _node* next;
struct _node* next; struct _node* prev;
void* data; void* data;
void (*delete_func)(void*); void (*delete_func)(void*);
} AWNode; } AWNode;
/** /**
...@@ -30,13 +30,12 @@ typedef struct _node ...@@ -30,13 +30,12 @@ typedef struct _node
* @param curr current position of list * @param curr current position of list
* @param free_me need to free itself or not * @param free_me need to free itself or not
*/ */
typedef struct _linked_list typedef struct _linked_list {
{ AWNode* head; /* dummy node */
AWNode* head; AWNode* tail; /* last node */
AWNode* tail; AWNode* iter; /* iterator */
AWNode* curr; int free_me;
int free_me; int cnt;
int cnt;
} AWList; } AWList;
/** /**
...@@ -45,8 +44,8 @@ typedef struct _linked_list ...@@ -45,8 +44,8 @@ typedef struct _linked_list
* @param pos AWNode *, Iterator variable * @param pos AWNode *, Iterator variable
* @param list List head * @param list List head
*/ */
#define AWList_for_each(pos, list) \ #define AWList_for_each(pos, list) \
for (pos = list->head; pos != NULL; pos = pos->next) for (pos = list->head; pos != NULL; pos = pos->next)
/** /**
* @brief allocate memory for list * @brief allocate memory for list
...@@ -110,7 +109,8 @@ void AWList_add_tail(AWList* list, void* data, void (*delete_func)(void*)); ...@@ -110,7 +109,8 @@ void AWList_add_tail(AWList* list, void* data, void (*delete_func)(void*));
* *
* @return the pointer of the node if exists, NULL if not found * @return the pointer of the node if exists, NULL if not found
*/ */
AWNode* AWList_find_node(AWList* list, void* data, AWNode* AWList_find_node(AWList* list,
void* data,
int (*cmp_callback)(void*, void*)); int (*cmp_callback)(void*, void*));
/** /**
......
#include <stdio.h>
#include <stdlib.h>
#include "AWList.h"
static inline void mfree(void* arg) {
free(arg);
arg = NULL;
}
int main() {
AWList list = {0};
AWList_init(&list);
int* num[10] = {NULL};
for (int i = 0; i < 10; ++i) {
num[i] = calloc(1, sizeof(int));
*num[i] = i;
AWList_add_tail(&list, num[i], mfree);
}
AWNode* node = NULL;
for (node = list.head->next; node != list.tail->next; node = node->next) {
printf("%d ", *(int*)node->data);
}
printf("\n");
AWList_clear(&list);
/* while ((node = AWList_iterator(&list))) { printf("%d ", *(int*)node->data); } */
/* printf("\n"); */
AWList_destroy(&list);
}
==240== Memcheck, a memory error detector
==240== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==240== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==240== Command: ./tests
==240== Parent PID: 84
==240==
==240==
==240== HEAP SUMMARY:
==240== in use at exit: 0 bytes in 0 blocks
==240== total heap usage: 22 allocs, 22 frees, 1,416 bytes allocated
==240==
==240== All heap blocks were freed -- no leaks are possible
==240==
==240== For lists of detected and suppressed errors, rerun with: -s
==240== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论