Algorithms之单链表

  链表是一种基础数据结构,亦是一种线性结构。除最后一个节点和第一个节点外,每个节点有且仅有一个前趋且有且仅有一个后继。第一个节点无前趋,最后一个节点无后继。单链表是链表的一种,包括数据域和指向下一个节点的指针域。通常定义在其上的插入,删除只需要调整指针指向,因此只需要O(1)的时间,但搜索需要遍历整个链表,因此需要O(n)的时间。

头文件——定义了List的数据结构及操作接口:

 1 /*************************************************************************
 2     > File Name: list.h
 3     > Author: hyolin
 4     > Created Time: Wed 14 Jan 2015 08:15:49 PM CST
 5  ************************************************************************/
 6 
 7 #ifndef LIST_H
 8 #define LIST_H
 9 
10 #include <stdlib.h>
11 
12 typedef int (*fun_com)(const void *, const void *) ;
13 typedef void (*func_des)(void *) ;
14 
15 /**Define a structure for linked list elements*/
16 typedef struct ListNode_
17 {
18     void *data ;
19     struct ListNode_ *next ;
20 } ListNode;
21 
22 /**Define a structure for linked lists*/
23 typedef struct List_ 
24 {
25     int size ;
26     func_com *compare ;
27     func_des *destroy ;
28     ListNode *head ;
29     ListNode *tail ;
30 } List ;
31 
32 /**List Interface*/
33 int list_init (List **list, func_com *compare, func_des *destroy) ;
34 void list_destroy (List *list) ;
35 /**Insert success return 0,failure return -1*/
36 int  list_ins_next (List *list, ListNode *element, const void *data) ;
37 
38 /**Remove success return 0, failure return -1*/
39 int  list_rm_next (List *list, ListNode *element, void **data) ;
40 
41 ListNode* list_search (const List *list, const void *data, ListNode **prev) ;
42 
43 /**return the size of list*/
44 #define list_size(list) (list)->size
45 /**return the head of list*/
46 #define list_head(list) (list)->head
47 /**return the tail of list*/
48 #define list_tail(list) (list)->tail
49 #define list_is_head(list, element) ((element) == (list)->head ?1 : 0))
50 #define list_is_tail(element) ((element)->next == NULL ? 1 : 0)
51 #define list_data(element) ((element)->data)
52 #define list_next(element) ((element)->next)
53 
54 #endif

 

//实现

/*************************************************************************
    > File Name: list.c
    > Author: hyolin
    > Created Time: Wed 14 Jan 2015 09:34:33 PM CST
 ************************************************************************/
#include <stdio.h> 
#include <stdlib.h>
#include <string.h>

 #include "list.h"

/*Initialize the list*/
int list_init (List **list, func_com *compare, func_des *destroy)
{
    int ret = 0 ;
    *list = NULL ;
    if ((*list = (List*)malloc(sizeof(List))) == NULL)
    {
        ret = -1 ;
        printf("%s %s %dfailure for malloc error: %d\n",__FILE__, __func__, __LINE__, ret) ;
        return ret ;
    }
    (*list)->size = 0 ;
    (*list)->compare = compare ;
    (*list)->destroy = destroy ;
    (*list)->head = NULL ;
    (*list)->tail = NULL ;
    
    return ret ;
}

/*list_destroy*/
void list_destroy (List *list)
{
    void    *data ;
    while (list_size (list) > 0)
    {
        if (list_rm_next(list, NULL, (void **)&data) == 0 && list->destroy
            != NULL)
        {
            list->destroy(data) ;//call a user-defined function to free dynamically data
        }
    }

    //memset(list, 0, sizeof(list)) ;
    if (list != NULL)
        free(list) ;

    return ;
}

/**list_ins_next*/
int list_ins_next (List *list, ListNode *element, const void *data)
{
    int ret = 0 ;

    if (list == NULL || data == NULL)
    {
        ret = -1 ;
        printf("%s %s %d list == NULL || data == NULL %d\n",__FILE__, __func__, __LINE__, ret) ;
        return ret ;
    }
    ListNode    *newNode ;

    /* Allocate storage for the element */
    if ((newNode = (ListNode *)malloc(sizeof(newNode))) == NULL)
    {
        ret = -2 ;
        printf("%s %s %d malloc error : %d\n", __FILE__, __func__, __LINE__, ret) ;
        return ret ;
    }

    /* Insert the element into the list */
    newNode->data = (void *)data ;
    if (element == NULL)
    {
        /* Handle the head of the list */
        if (list_size(list) == 0)
            list->tail = newNode ;

        newNode->next = list->head ;
        list->head = newNode ;
    }
    else {
        if (element->next == NULL)
            list->tail = newNode ;

        newNode->next = element->next ;
        element->next = newNode ;
    }
    /*Adjust the size of the list */
    list->size++ ;

    return ret ;
}
   
/* list_rm_next */
int list_rm_next (List *list, ListNode *element, void **data)
{
    int ret = 0 ;
    ListNode    *oldNode ;
    /* Don't allow remove from an empty list */
    if (list == NULL || list_size(list) == 0)
    {
        ret = -1 ;
        printf("%s %s %d failure  %d",__FILE__, __func__, __LINE__, ret) ;
        return ret ;
    }

    if (element == NULL)
    {
        *data = list->head->data ;
        oldNode = list->head ;
        list->head = list->head->next ;

        if (list_size(list) == 1)
            list->tail = NULL ;
    }
    else {
        if (element->next == NULL)
        {

            ret = -2 ;
            printf("%s %s %d failure: element next is empty %d",__FILE__, __func__, __LINE__, ret) ;
            return ret ;
        }

        oldNode = element->next ;
        *data = oldNode->data ;
        element->next = element->next->next ;
        
        if (element->next ==NULL)
            list->tail = element ;    
    }

    free(oldNode) ;
    list->size-- ;

    return ret ;
}

/* list_search */
ListNode* list_search (const List *list, const void *data, ListNode **prev/*,
                        int (*compare)(const void *key1, const void *key2)*/)
{
    int ret = 0 ;
    if (list == NULL || data == NULL)
    {
        ret = -1 ;
        printf("%s %s %d failure: list ==  NULL or data == NULL %d",__FILE__, __func__, __LINE__, ret) ;
        return ret ;
    }
    /** Return the data of the list node */
    ListNode *element = list_head(list) ;
    *prev = NULL ;

    while (element)
    {
        if (list->compare(element->data, data) == 0)
            break ;
        prev = element ;
        element = element->next ;
    }
    /* 
     for (; element != NULL; element = list_next(element))
     {
        if (compare(list_data(element) == 0))
            break ;
        prev = element ;
     }
     */
    return element ;
}

 //测试函数

 1 /*************************************************************************
 2     > File Name: list_test.c
 3     > Author: hyolin 
 4     > Created Time: Thu 15 Jan 2015 01:56:48 PM CST
 5  ************************************************************************/
 6 
 7 #include <stdio.h>
 8 
 9 #include "list.h"
10 
11 
12 typedef struct st_ {
13     int age ;
14 } st ;
15 
16 void destroy(void *data)
17 {
18     if (data != NULL)
19         free(data);
20     data = NULL ;
21 }
22 void print_list (List *list)
23 {
24     ListNode * p = NULL ;
25     if (list == NULL)
26         return ;
27     p = list->head ;
28     while (p)
29     {
30         printf("listNode:%d\n", *(int *)p->data) ;
31         p = p->next ;
32     }
33 }
34 
35 /* List testing function */
36 int list_test ()
37 {
38     st *data = NULL ;
39     List *list = NULL ;
40 
41     list_init(&list, NULL, destroy) ;
42 
43     int i ;
44     st *d[10] ;
45     for (i = 0; i <10; i++)
46     {
47         d[i] = NULL ;
48         if ((d[i] = (st*)malloc(sizeof(st))) == NULL)
49             return -1 ;
50         d[i]->age = i ;
51         list_ins_next(list, NULL, (void*)d[i]) ;
52         printf("list:%p size:%d\n",list->head->data,list->size) ;
53     }
54 
55     print_list(list) ;
56 
57     list_rm_next(list, NULL, (void**)&data) ;
58     destroy((void*)data) ;
59     
60     print_list(list) ;
61     
62     list_destroy(list) ;
63     
64     return 0 ;
65 }
66 
67 int main ()
68 {
69     list_test() ;
70     return 0 ;
71 }

测试结果:

posted on 2015-02-05 16:38  子墨sky  阅读(103)  评论(0)    收藏  举报

导航