C语言面向对象编程(五):单链表实现(三)

2014-11-23 20:15:39 · 作者: · 浏览: 54
} return list; } static int _length_of(struct single_list * list) { return list->size; } static void _clear_list(struct single_list * list) { struct slist_node * p = list->head; struct slist_node * p2; while(p) { p2 = p; p = p->next; if(list->free_node) list->free_node(p2); else free(p2); } list->head = 0; list->tail = 0; list->size = 0; } static void _delete_single_list(struct single_list *list) { list->clear(list); free(list); } struct single_list * new_single_list(list_op_free_node op_free, list_op_key_hit_test op_cmp) { struct single_list *list = (struct single_list *)malloc(sizeof(struct single_list)); list->head = 0; list->tail = 0; list->size = 0; list->free_node = op_free; list->key_hit_test = op_cmp; list->add = _add_node; list->insert = _insert_node; list->replace = _replace; list->find_by_key = _find_by_key; list->first = _first_of; list->last = _last_of; list->at = _node_at; list->take_at = _take_at; list->take_by_key = _take_by_key; list->remove = _remove_node; list->remove_at = _remove_at; list->remove_by_key = _remove_by_key; list->length = _length_of; list->clear = _clear_list; list->deletor = _delete_single_list; return list; }
上面的代码就不一一细说了,下面是测试代码:

/* call 1 or N arguments function of struct */
#define ST_CALL(THIS,func,args...) ((THIS)->func(THIS,args))

/* call none-arguments function of struct */
#define ST_CALL_0(THIS,func) ((THIS)->func(THIS))

struct int_node {
    struct slist_node node;
    int id;
};

struct string_node {
    struct slist_node node;
    char name[16];
};


static int int_free_flag = 0;
static void _int_child_free(struct slist_node *node)
{
    free(node);
    if(!int_free_flag)
    {
        int_free_flag = 1;
        printf("int node free\n");
    }
}

static int _int_slist_hittest(struct slist_node * node, void *key)
{
    struct int_node * inode = NODE_T(node, struct int_node);
    int ikey = (int)key;
    return (inode->
id == ikey 0 : 1); } static int string_free_flag = 0; static void _string_child_free(struct slist_node *node) { free(node); if(!string_free_flag) { string_free_flag = 1; printf("string node free\n"); } } static int _string_slist_hittest(struct slist_node * node, void *key) { struct string_node * sn = (struct string_node*)node; return strcmp(sn->name, (char*)key); } void int_slist_test() { struct single_list * list = new_single_list(_int_child_free, _int_slist_hittest); struct int_node * node = 0; struct slist_node * bn = 0; int i = 0; printf("create list && nodes:\n"); for(; i < 100; i++) { node = (struct int_node*)malloc(sizeof(struct int_node)); node->id = i; if(i%10) { list->add(list, node); } else { list->insert(list, 1, node); } } printf("create 100 nodes end\n----\n"); printf("first is : %d, last is: %d\n----\n", NODE_T( ST_CALL_0(list, first), struct int_node )->id, NODE_T( ST_CALL_0(list, last ), struct int_node )->id); assert(list->size == 100); printf("list traverse:\n"); for(i = 0; i < 100; i++) { if(i%10 == 0) printf("\n"); bn = list->at(list, i); node = NODE_T(bn, struct int_node); printf(" %d", node->id); } printf("\n-----\n"); printf("find by key test, key=42:\n"); bn = list->find_by_key(list, (void*)42); assert(bn != 0); node = NODE_T(bn, struct int_node); printf("find node(key=42), %d\n------\n", node->id); printf("remove node test, remove the 10th node:\n"); bn = list->at(list, 10); node = NODE_T(bn, struct int_node); printf(" node 10 is: %d\n", node->id); printf(" now remove node 10\n"); list->remove_at(lis