C语言实现通用链表

 数据结构

struct node_t {
    void *container;
    struct node_t *next;
};

typedef struct task {
    char *name;
    int xvalue;
    struct node_t node;
} task_t;

typedef struct ready_list {
    char *name;
    struct node_t head;
} list_t;

图解

链表初始化

void init_list(list_t *new_list)
{
    new_list->name = "ready";
    new_list->head.next = NULL;
}

链表尾插

void insert_node_end(list_t *p_list, struct node_t *new_node)
{
    struct node_t *cur = &p_list->head;
    while (cur != NULL && cur->next != NULL) {
        cur = cur->next;
    }
    cur->next = new_node;
    new_node->next = NULL;
}

链表删除

void delete_node(list_t *p_list, struct node_t *new_node)
{
    struct node_t *cur = &p_list->head;
    if (cur == NULL) {
        return;
    }
    while (cur != NULL && cur->next != new_node) {
        cur = cur->next;
    }
    if (cur) {
        cur->next = new_node->next;
        new_node->next = NULL;
    } else {
        printf("no delete element\n");
    }
}

链表排序

/* 选择排序 */
void insert_after_list(struct node_t *pre,struct node_t *new_node)
{
    if (new_node != NULL && pre != NULL) {
        new_node->next = pre->next;
        pre->next = new_node;
    }
}

void sort_node(list_t *p_list)
{
    task_t *p1, *p2;
    struct node_t *pre1 = &p_list->head;
    struct node_t *cur = p_list->head.next;
    struct node_t *next, *pre2, *tmp;
    while (cur->next) {
        pre2 = cur;
        next = cur->next;
        while (next) {
            //p1 = container_of(cur, task_t, node);
            //p2 = container_of(next, task_t, node);
            LIST_GET_CONTAINER(p1, cur);
            LIST_GET_CONTAINER(p2, next);
            if (p1->xvalue > p2->xvalue) {
                delete_node(p_list, cur);
                delete_node(p_list, next);
                insert_after_list(pre1, next);
                if (cur != pre2) {
                    insert_after_list(pre2, cur);
                } else {
                    insert_after_list(next, cur);
                }
                tmp = cur;
                cur = next;
                next = tmp;
            }
            pre2 = next;
            next = next->next;
        }
        pre1 = cur;
        cur = cur->next;
    }
}

链表打印

void print_node(list_t *p_list)
{
    task_t *p_item;
    struct node_t *cur = p_list->head.next;
    if (cur == NULL) {
        return;
    }
    while (cur != NULL) {
        //p_item = container_of(cur, task_t, node);
        LIST_GET_CONTAINER(p_item, cur);
        printf("%s -- %d\n",p_item->name, p_item->xvalue);
        cur = cur->next;
    }
    printf("\n");
}

测试用例

#include <stdio.h>
#include <string.h>
#include <stddef.h> 

#define container_of(ptr, type, member) \
                        ((type*)((char*)(ptr) - offsetof(type, member)))
/* 传递结构体成员的地址本身就是传递了指向该成员的指针 */
#define LIST_SET_CONTAINER(node_ptr, task_ptr) \
                        ((node_ptr)->container = (void*)(task_ptr)) 

#define LIST_GET_CONTAINER(task_ptr, node_ptr) \
                        ((task_ptr) = (task_t*)(node_ptr)->container)


int main() 
{
    int i = 0;
    list_t ready_list;

    init_list(&ready_list);

    task_t list_node[] = {
        {"task0", 50, {NULL}},
        {"task1", 20, {NULL}}, 
        {"task2", 30, {NULL}},
        {"task4", 10, {NULL}},
        {"NULL", 0, {NULL}}
    };
    while (list_node[i].name != "NULL") {
        insert_node_end(&ready_list, &list_node[i].node);
        LIST_SET_CONTAINER(&(list_node[i].node), &list_node[i]);
        i++;
    }
    print_node(&ready_list);
    // delete_node(&ready_list, &list_node[0].node);
    // delete_node(&ready_list, &list_node[3].node);
    // print_node(&ready_list);
    sort_node(&ready_list);
    print_node(&ready_list);
    return 0;
}

指定节点前插入新节点

void insert_node_end(list_t *p_list, struct node_t *new_node)
{
    struct node_t *p_item = p_list->p_item; /* 在 p_item 之前插入新节点 */
    
    new_node->next = p_item;
    new_node->pre = p_item->pre;
    p_item->pre->next = new_node;
    p_item->pre = new_node;
}

void delete_node(list_t *p_list, struct node_t *new_node)
{
    new_node->pre->next = new_node->next;
    new_node->next->pre = new_node->pre;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值