C理解(四):链表

本文主要探讨单链表与双链表相关知识。

linux内核链表(include/linux/list.h)
        内核链表中纯链表封装,纯链表的各种操作函数(节点创建、插入、删除、遍历······),纯链表内嵌在驱动结构体中,实现驱动的创建、插入、删除、遍历等

单链表 

        单链表链表头插入节点,尾插入节点,删除节点,逆序

代码示例:

#include <stdio.h>
#include <stdlib.h>

struct node
{
        int data;
        struct node *next;
};

//创建节点
struct node * create_node(int data)
{
        struct node *p = (struct node *)malloc(sizeof(struct node));
        if(p == NULL)
        {
                printf("malloc error\n");
        return NULL;
        }
        p->data = data;
        p->next = NULL;
        return p;
}

//头部插入节点
void insert_head(struct node *phead,struct node *new)
{
        struct node *p = phead;
        if(p == NULL)
                exit(0);
        new->next = p->next;
        p->next = new;
        (phead->data)++;        //头节点存储节点数量
}

//尾部插入
void insert_tail(struct node *phead,struct node *new)
{
        struct node *p = phead;
        if(p == NULL)
                exit(0);
        while(p->next != NULL)
        {
                p = p->next;
        }
        p->next = new;
        (phead->data)++;        //头节点存储节点数量
}

//遍历链表
void printf_link(struct node *phead)
{
        if(phead == NULL)
        exit(0);
        struct node *p = phead;
        printf("num of struct : %d \n",p->data);
        while(p->next != NULL)
        {
                p = p->next;
                printf("struct data : %d\n",p->data);
        }
}

//删除节点
int  delete_node(struct node *phead,int data)
{
        if(phead == NULL)
        exit(-1);
        struct node *p = phead;
        struct node *prev = NULL;
        while(p->next != NULL)
        {
                prev = p;
                p = p->next;
                if(p->data == data)
                {
                        if(p->next != NULL)
                        {
                                prev->next = p->next;   //其他节点
                                free(p);
                        }
                        else
                        {
                                prev->next = NULL;      //尾节点
                                free(p);
                        }
                        (phead->data)--;
                        return 0;
                }
        }
        printf("have no data\n");
        return -1;
}

//链表逆序
void reserve_link(struct node *phead)
{
        if(phead == NULL)
        exit(-1);
        struct node *p = phead->next;
        struct node *back = NULL;
        struct node *prev = NULL;
        if(p->next == NULL || p == NULL)        //只有一个节点,不逆序
        return ;
        while(p->next != NULL)                  //两个及两个以上节点
        {
                back = p->next;                 //保存链表的下一个节点,由于头插逆序法插入节点与后面节点断开
                if(p == phead->next)            //第一个节点指向NULL作为逆序首节点
                {
                        p->next = NULL;
                }
                else
                {
                        p->next = phead->next;
                }
                phead->next = p;
                p = back;
        }
        insert_head(phead,p);   //最后一个节点插入到链表,由于最后一个节点指向NULL,while判断失效
        (phead->data)--;        //头插最后一个节点时,默认新增一个节点
}

int main()
{
        //创建头节点
        struct node *head = create_node(0);

        //头部插入节点
        insert_head(head,create_node(1));
        insert_head(head,create_node(2));
        insert_head(head,create_node(3));
        insert_head(head,create_node(4));
        insert_head(head,create_node(5));

        //尾部插入节点
        insert_tail(head,create_node(1));
        insert_tail(head,create_node(2));
        insert_tail(head,create_node(3));
        insert_tail(head,create_node(4));
        insert_tail(head,create_node(5));

        //遍历节点
        printf_link(head);

        //删除节点
        delete_node(head,5);
        delete_node(head,5);
        delete_node(head,4);

        //遍历节点
        printf_link(head);

        //链表逆序
        reserve_link(head);

        //遍历节点
        printf_link(head);

        return 0;
}

结果示例:

双链表

        双链表尾插入,头插入,删除节点,前向遍历,后向遍历 

代码示例:

#include <stdio.h>
#include <stdlib.h>

struct node
{
        int data;
        struct node *next;
        struct node *prev;
};

//创建节点
struct node * create_node(int data)
{
        struct node *p = (struct node *)malloc(sizeof(struct node));
        if(p == NULL)
        {
                printf("malloc error\n");
                return NULL;
        }
        p->data = data;
        p->next = NULL;
        p->prev = NULL;
        return p;
}

//头部插入节点
void insert_head(struct node *phead,struct node *new)
{
        struct node *p = phead;
        if(p == NULL)
                exit(0);
        new->next = p->next;
        if(p->next != NULL)
        p->next->prev = new;
        p->next = new;
        new->prev = p;
        (phead->data)++;        //头节点存储节点数量
}

//尾部插入
void insert_tail(struct node *phead,struct node *new)
{
        struct node *p = phead;
        if(p == NULL)
        exit(0);
        while(p->next != NULL)
        {
                p = p->next;
        }
        p->next = new;
        new->prev = p;
        new->next = NULL;
        (phead->data)++;        //头节点存储节点数量
}

//后项遍历链表
void next_printf_link(struct node *phead)
{
        if(phead == NULL)
        exit(0);
        struct node *p = phead;
        printf("num of struct : %d \n",p->data);
        while(p->next != NULL)
        {
                p = p->next;
                printf("struct data : %d\n",p->data);
        }
}

//前项遍历链表
void prev_printf_link(struct node *phead)
{
        if(phead == NULL)
                exit(0);
        struct node *p = phead;
        printf("num of struct : %d \n",p->data);
        while(p->next != NULL)
        {
                p = p->next;
        }
        while(p->prev != NULL)
        {
                printf("struct data : %d\n",p->data);
                p = p->prev;
        }
}

//删除节点
int  delete_node(struct node *phead,int data)
{
        if(phead == NULL)
        exit(-1);
        struct node *p = phead;
        struct node *test = NULL;
        while(p->next != NULL)
        {
                p = p->next;
                if(p->data == data)
                {
                        if(p->next == NULL)
                        {
                                p->prev->next = NULL;   //尾节点
                        }
                        else
                        {
                                //其他节点
                                p->prev->next = p->next;
                                p->next->prev = p->prev;
                        }
                        free(p);
                        (phead->data)--;
                        return 0;
                }
        }
        printf("have no data\n");
        return -1;
}

int main()
{
        //创建头节点
        struct node *head = create_node(0);

        //头部插入节点
        insert_head(head,create_node(1));
        insert_head(head,create_node(2));
        insert_head(head,create_node(3));
        insert_head(head,create_node(4));
        insert_head(head,create_node(5));

        //尾部插入节点
        insert_tail(head,create_node(1));
        insert_tail(head,create_node(2));
        insert_tail(head,create_node(3));
        insert_tail(head,create_node(4));
        insert_tail(head,create_node(5));

        //遍历节点
        next_printf_link(head);

        //删除节点
        delete_node(head,2);
        delete_node(head,5);
        delete_node(head,4);

        //next遍历节点
        next_printf_link(head);

        //prev遍历节点
        prev_printf_link(head);
        return 0;
}

结果示例:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值