C语言通用链表程序源码

#include <stdio.h>
#include <string.h>
#include <malloc.h>
//通用链表结构
struct list_head {
         struct list_head *next, *prev;
};

typedef struct tag_student
{
    int  age;
    double score;
    struct list_head list;
}STU;

#define PT(stVar) printf("%d %.2f \n", (stVar)->age, (stVar)->score)

//定义并初始化链表头
#define HEAD_INIT(head) struct list_head head = {&head, &head}

//从表头添加新节点
static void addNode(struct list_head *newNode, struct list_head *head)
{
    newNode->next = head->next;    
    newNode->prev = head;
    head->next->prev = newNode;
    head->next = newNode;
}

//遍历链表(不能用于遍历时删除节点)
#define LIST_SEARCH_FOR_FORWARD(head, pos) for((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
#define LIST_SEARCH_FOR_BACKWARD(head, pos) for((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)

//遍历链表(只能用于遍历时删除节点)
#define LIST_SEARCH_FOR_DEL_FORWARD(head, pos, bak) for(pos = (head)->next, bak = pos->next; pos != (head); pos = bak, bak = bak->next)
#define LIST_SEARCH_FOR_DEL_BACKWARD(head, pos, bak) for(pos = (head)->prev, bak = pos->prev; pos != (head); pos = bak, bak = bak->prev)  

//根据list成员获取结构体的指针
#define LIST_ENTRY(node, list, type) (type *)((char *)(node) - (unsigned long)&(((type *)0)->list))

//删除一个节点
static void NodeDel(struct list_head *Node)
{
    Node->prev->next = Node->next;
    Node->next->prev = Node->prev;
}

int main(int argc, char *argv[])
{
    int i=0;
    struct list_head *pos = NULL;
    struct list_head *bak = NULL;
    HEAD_INIT(head);

    //添加节点
    for(i = 0; i < 5; i ++)
    {
        STU *tmp = NULL;
        tmp = (STU *)calloc(1, sizeof(STU));        
        tmp->age = 35+i;
        tmp->score = 35.6+i;
        addNode(&tmp->list, &head);
    }
    LIST_SEARCH_FOR_BACKWARD(&head, pos)
    {
        STU *temp = NULL;
        temp = LIST_ENTRY(pos, list, STU);
        PT(temp);
    }
    //删除年龄为37的节点
    LIST_SEARCH_FOR_DEL_BACKWARD(&head, pos, bak)
    {
        STU *temp = NULL;
        temp = LIST_ENTRY(pos, list, STU);
        if(temp->age == 37)
        {
            NodeDel(&temp->list);
            free(temp);
        }
    }
    printf("after del the node whose age is 37\n");
    //删除年龄为37的节点后
    LIST_SEARCH_FOR_BACKWARD(&head, pos)
    {
        STU *temp = NULL;
        temp = LIST_ENTRY(pos, list, STU);
        PT(temp);
    }
    //释放链表
    LIST_SEARCH_FOR_DEL_BACKWARD(&head, pos, bak)
    {
        STU *temp = NULL;
        temp = LIST_ENTRY(pos, list, STU);
        NodeDel(&temp->list);
        free(temp);
    }
    //释放链表后再去遍历,看是效果
    LIST_SEARCH_FOR_BACKWARD(&head, pos)
    {
        printf("a\n");
    }
    LIST_SEARCH_FOR_FORWARD(&head, pos)
    {
        printf("b\n");
    }
    return 0;
}

You may also like...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据