c语言 单向链表企业版(插入、遍历、删除、销毁)

本文详细介绍了一个自定义链表的数据结构实现方法,包括链表的初始化、插入、遍历、删除和销毁等核心功能,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、功能介绍

1.1、链表结构体设计

链表节点只维护指针域,数据域,由用户给
// 链表结构体结构体
struct Link
{
    struct Link* next;  // 只维护指针域
};

// 用来维护链表
struct Links
{
    struct Link head;	// 链表头节点
    int m_size;	// 链表节点个数
};

// 自定义类型,为了隐藏Links结构体,不需要使用者破坏
typedef void* Linklinks;	

1.2、链表初始化

Linklinks init_Link(void)
{
    struct Links* link = (struct Links*)malloc(sizeof(struct Links));
    if(link==NULL)
        return NULL;
    
    link->head.next = NULL;
    link->m_size = 0;
    
    return link;
}

1.3、插入

// 测试数据结构体
struct person1
{
    void* node; // 预留4个字节
    char name[64];
    int age;
};

void insert_Link(Linklinks list,int pos,void* data)
{
    if(list==NULL||data==NULL)
        return;
    struct Links* mylist = (struct Links*)list;
    if(pos<0||pos>mylist->m_size-1)
        pos = mylist->m_size;

    // 用户数据前4个字节,由我们来使用
    struct Link* mynode = (struct Link*)data;
    struct Link* head = &(mylist->head);
    
    for(int i=0;i<pos;i++)
    {
        head = head->next;
    }
    // 更新指针指向
    mynode->next = head->next;
    head->next = mynode;
    mylist->m_size++;

}

1.4、遍历

// 遍历
void foreach_Link(Linklinks list,void(*myfor)(void*))
{
    if(list==NULL)
        return;
    struct Links* mylist = (struct Links*)list;
    struct Link* head = mylist->head.next;
    
    for(int i=0;i<mylist->m_size;i++)
    {
        myfor(head);
        head = head->next;
    }
    
}
void myPrintPerson1(void* data)
{
    struct person1* p = (struct person1*)data;
    printf("%s %d\n",p->name,p->age);
}

1.5、删除

// 删除 下标删除
void remove_Link(Linklinks list,int pos)
{
    if(list==NULL)
        return;
    struct Links* mylist = (struct Links*)list;
    if(pos<0||pos>mylist->m_size-1)
        return;
    
    struct Link* head = &(mylist->head);
    for(int i=0;i<pos;i++)
    {
        head = head->next;
    }
    struct Link* temp = head->next;
    head->next = temp->next;
    
    mylist->m_size--;
}

int mycomparePerson1(void* data1,void* data2)
{
    struct person1* p1 = data1;
    struct person1* p2 = data2;
    return strcmp(p1->name, p2->name)==0 && p1->age == p2->age;
}
// 按照值删除
void remove_Link_value(Linklinks list,void* data,int(*mycompare)(void*,void*))
{
    if(list==NULL || data==NULL)
        return;
    
    struct Links* mylist = (struct Links*)list;
    struct Link* head = &(mylist->head);
    struct Link* head1 = mylist->head.next;
    
    for(int i=0;i<mylist->m_size;i++)
    {
        if(mycompare(head1,data))
        {
            head->next = head1->next;
            mylist->m_size--;
            break;
        }
        head = head->next;
        head1 = head1->next;
    }
}

1.6、销毁

// 销毁数组
void destroy_Link(Linklinks list)
{
    if(list!=NULL)
    {
        free(list);
    }
    
}

2、代码

struct Link
{
    struct Link* next;  // 只维护指针域
};

// 链表结构体
struct Links
{
    struct Link head;
    int m_size;
};

typedef void* Linklinks;

Linklinks init_Link(void)
{
    struct Links* link = (struct Links*)malloc(sizeof(struct Links));
    if(link==NULL)
        return NULL;
    
    link->head.next = NULL;
    link->m_size = 0;
    
    return link;
}

// 插入
void insert_Link(Linklinks list,int pos,void* data)
{
    if(list==NULL||data==NULL)
        return;
    struct Links* mylist = (struct Links*)list;
    if(pos<0||pos>mylist->m_size-1)
        pos = mylist->m_size;

    // 用户数据前4个字节,由我们来使用
    struct Link* mynode = (struct Link*)data;
    struct Link* head = &(mylist->head);
    
    for(int i=0;i<pos;i++)
    {
        head = head->next;
    }
    // 更新指针指向
    mynode->next = head->next;
    head->next = mynode;
    mylist->m_size++;

}

// 遍历
void foreach_Link(Linklinks list,void(*myfor)(void*))
{
    if(list==NULL)
        return;
    struct Links* mylist = (struct Links*)list;
    struct Link* head = mylist->head.next;
    
    for(int i=0;i<mylist->m_size;i++)
    {
        myfor(head);
        head = head->next;
    }
    
}

// 测试
struct person1
{
    void* node; // 预留4个字节
    char name[64];
    int age;
};

void myPrintPerson1(void* data)
{
    struct person1* p = (struct person1*)data;
    printf("%s %d\n",p->name,p->age);
}

// 删除 下标删除
void remove_Link(Linklinks list,int pos)
{
    if(list==NULL)
        return;
    struct Links* mylist = (struct Links*)list;
    if(pos<0||pos>mylist->m_size-1)
        return;
    
    struct Link* head = &(mylist->head);
    for(int i=0;i<pos;i++)
    {
        head = head->next;
    }
    struct Link* temp = head->next;
    head->next = temp->next;
    
    mylist->m_size--;
}

int mycomparePerson1(void* data1,void* data2)
{
    struct person1* p1 = data1;
    struct person1* p2 = data2;
    return strcmp(p1->name, p2->name)==0 && p1->age == p2->age;
}

void remove_Link_value(Linklinks list,void* data,int(*mycompare)(void*,void*))
{
    if(list==NULL || data==NULL)
        return;
    
    struct Links* mylist = (struct Links*)list;
    struct Link* head = &(mylist->head);
    struct Link* head1 = mylist->head.next;
    
    for(int i=0;i<mylist->m_size;i++)
    {
        if(mycompare(head1,data))
        {
            head->next = head1->next;
            mylist->m_size--;
            break;
        }
        head = head->next;
        head1 = head1->next;
    }
}
            
// 销毁数组
void destroy_Link(Linklinks list)
{
    if(list!=NULL)
    {
        free(list);
    }
    
}

void test02(void)
{
    // 初始化链表
    Linklinks mylist = init_Link();
    
    // 创建数据
    struct person1 p1 = {NULL,"aaa",12};
    struct person1 p2 = {NULL,"bbb",52};
    struct person1 p3 = {NULL,"ccc",15};
    struct person1 p4 = {NULL,"ddd",32};
    
    insert_Link(mylist, 0, &p1);
    insert_Link(mylist, 0, &p2);
    insert_Link(mylist, 0, &p3);
    insert_Link(mylist, 0, &p4);
    
    // 删除
    struct person1 p5 = {NULL,"ddd",32};
    remove_Link_value(mylist,&p5,mycomparePerson1);
    
    // 遍历链表
    foreach_Link(mylist, myPrintPerson1);
}



int main(int argc, const char * argv[])
{
    test02();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讳疾忌医丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值