Linux wlan 内核开发之双链表操作

源码

直接编译完成验证

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义双链表节点
struct node {
int data ;
struct node *prenode ;
struct node *nextnode ;
};
//创建新节点的函数
struct node *create_node(int node_value )
{
struct node * new_node = malloc(sizeof(struct node)) ;
//检查内存分配
if(new_node == NULL)
    {
        printf("内存分配失败!\n");
        return NULL;
    }

//初始化节点    
new_node->data = node_value ;
new_node->prenode = NULL ;
new_node->nextnode = NULL ;

printf("创建节点成功,数据 = %d,地址 = %p\n", new_node->data, new_node);

return new_node ;

}
//连接节点,形成双链表
void connect_node(struct node *first_node,struct node *second_node)
{
if (first_node == NULL || second_node == NULL) {
printf("错误:节点不能为空!\n");
return;
}
first_node->nextnode = second_node ;
second_node->prenode = first_node ;
}
//创建链表管理结构,为了更好地管理链表
struct DoublyLinkList{
struct  node *head;//头节点
struct  node *tail;//尾节点
int size ;//链表大小
};
//初始化链表
struct DoublyLinkList* create_none_list() {
struct DoublyLinkList* list = (struct DoublyLinkList*)malloc(sizeof(struct DoublyLinkList));
list->head = NULL;
list->tail = NULL;
list->size = 0;
printf("创建了新的空链表\n");
return list;
}
//插入节点到指定位置,eg:position == 2:新节点作为第2个几点
void add_node_in_list(struct DoublyLinkList* list, int position, int node_value)
{
struct node * new_node = create_node(node_value);
if(position > list->size)//超过链表大小,就插入尾节点
    {
        printf("超过链表大小,就插入尾节点\n");
        if(list->head == NULL)// 链表为空,新节点既是头也是尾
        {
            printf("新的空链表\n");
            list->head  =  new_node ;
            list->tail  =  new_node ;
        }
        else{// 链表不为空,添加到尾部
            printf("不是空链表\n");
            list->tail->nextnode = new_node ;//新节点传给为节点的next域
            new_node->prenode = list->tail ;
            list->tail = new_node ; //尾节点跳至新节点地址
        }    
    }
else
    {
        struct node * current_node = list->head ;
        
        for(int i = position ; i > 2 ; i--)
            {
                current_node = current_node->nextnode ;
            }
        
        printf("加在 %p:%d 节点后\n",current_node,current_node->data);
        new_node->nextnode = current_node->nextnode ;//新节点的下一个节点地址给到新节点的next域
        current_node->nextnode->prenode = new_node ;//新节点的下一个节点的pre域指向新节点地址
        new_node->prenode =  current_node ; //新节点的pre域指向前一个节点地址
        current_node->nextnode = new_node ;//新节点给到前一个节点的next域
    }

list->size++;
printf("链表size大小变为:%d\n",list->size);

}
//在链表尾部添加节点
void append_node(struct DoublyLinkList* list , int node_value)
{
struct node * new_node = create_node(node_value);

if(list->head == NULL)// 链表为空,新节点既是头也是尾
    {
        printf("新的空链表\n");
        list->head  =  new_node ;
        list->tail  =  new_node ;
    }
else{// 链表不为空,添加到尾部
        printf("不是空链表\n");
        list->tail->nextnode = new_node ;//新节点传给为节点的next域
        new_node->prenode = list->tail ;
        list->tail = new_node ; //尾节点跳至新节点地址
    
    }
list->size++ ;
printf("链表大小为:%d\n",list->size);

}
//在链表头部添加节点
void preappend_node(struct DoublyLinkList* list ,int node_value)
{
struct node * new_node = create_node(node_value);
if(list->head == NULL)// 链表为空,新节点既是头也是尾
    {
        printf("新的空链表\n");
        list->head  =  new_node ;
        list->tail  =  new_node ;
    }
else{// 链表不为空,添加到尾部
        printf("不是空链表\n");
        list->head->prenode = new_node ;//新节点传给为节点的pre域
        new_node->nextnode = list->head ;
        list->head = new_node ; //尾节点跳至新节点地址
    
    }
list->size++ ;
printf("链表大小为:%d\n",list->size);

}
//删除指定位置的节点
void delete_local_node(struct DoublyLinkList* list , int position )
{
if(position > list->size)
    {
        printf("超过链表大小\n");
        return ;
    }
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;

for(int i = position ; i > 1 ; i--)
    {
        current_node = current_node->nextnode ;
    }

printf("被删除节点地址为:%p\n",current_node);

tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);


current_node->prenode->nextnode = current_node->nextnode ;//把删除节点的下一个节点地址给到删除节点上一个节点的next域
current_node->nextnode->prenode = current_node->prenode ;//把删除节点的前一个节点的地址给到删除节点的下一个节点的pre域
free(tmp_node);

list->size--;
printf("释放结束,size大小为:%d\n",list->size);

}
//删除头节点
void delete_head_node(struct DoublyLinkList* list )
{
if(list == NULL)
    {
        printf("链表为空\n");
        return ;
    }
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;

printf("被删除节点地址为:%p\n",current_node);

tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);

list->head =  current_node->nextnode ;//下一个节点给到头结点
current_node->nextnode->prenode = NULL ;//第二个节点的pre域指向 NULL

free(tmp_node);

printf("释放结束\n");

}
//删除尾节点
void delete_tail_node(struct DoublyLinkList* list )
{
if(list == NULL)
    {
        printf("链表为空\n");
        return ;
    }
struct node * current_node = list->tail ;
struct node * tmp_node = NULL ;

printf("被删除节点地址为:%p\n",current_node);

tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);

list->tail =  current_node->prenode ;//下一个节点给到头结点
current_node->prenode->nextnode = NULL ;//第二个节点的pre域指向 NULL
free(tmp_node);
printf("释放结束\n");

}
//根据值删除节点(删除第一个匹配的)
void delete_node_by_data(struct DoublyLinkList* list , int node_value )
{
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;
while(current_node->data != node_value)
    {
        current_node = current_node->nextnode ;
    }

printf("被删除节点地址为:%p\n",current_node);

tmp_node = current_node ; //要被释放的节点
printf("被释放的节点地址为:%p\n",tmp_node);


current_node->prenode->nextnode = current_node->nextnode ;//把删除节点的下一个节点地址给到删除节点上一个节点的next域
current_node->nextnode->prenode = current_node->prenode ;//把删除节点的前一个节点的地址给到删除节点的下一个节点的pre域
free(tmp_node);

list->size--;
printf("释放结束,size大小为:%d\n",list->size);

}
//清空整个链表
void delete_list_all(struct DoublyLinkList* list )
{
if(list == NULL)
    {
        printf("链表为空\n");
        return ;
    }
struct node * current_node = list->head ;

while(current_node != NULL)
    {
        current_node->data = 0;
        current_node = current_node->nextnode ;
    }

}
//根据data值,查找节点地址
struct node find_node_by_data(struct DoublyLinkList list , int node_value )
{
struct node * current_node = list->head ;
struct node * tmp_node = NULL ;
while(current_node != NULL )
    {
        if(current_node->data == node_value)
            {
                printf("找到节点,节点值为:%d\n",current_node->data);
                break ;
            }
        current_node = current_node->nextnode ;
    }


printf("找到节点,节点地址值为:%p\n",current_node);

return current_node;

}
//打印一个链表,从头到尾
void print_list_head(struct DoublyLinkList* list) {
if (list == NULL) {
printf("链表为空!\n");
return;
}
struct node *current_node = list->head;

printf("链表(从头到尾):");
while (current_node != NULL) {
    printf("%d", current_node->data);
    if (current_node->nextnode != NULL) {
        printf(" <-> ");
    }
    current_node = current_node->nextnode;
}
printf("\n");

}
//打印一个链表,从尾到头
void print_list_tail(struct DoublyLinkList* list) {
if (list == NULL) {
printf("链表为空!\n");
return;
}
struct node* current = list->tail;

printf("链表(从尾到头):");
while (current != NULL) {
    printf("%d", current->data);
    if (current->prenode != NULL) {
        printf(" <-> ");
    }
    current = current->prenode;
}
printf("\n");

}
//释放一个链表
void lease_list_node(struct DoublyLinkList * list_node)
{
struct node  *current =  list_node->head ;
struct node  *tmp_node =  NULL ;
while(current != NULL)
    {
        tmp_node = current ;//准备释放的节点
        current = current->nextnode ;//记录并跳到下一个节点
        printf("---释放的地址为:%p---\n",tmp_node);
        free(tmp_node);            
}    

}
int main()
{
struct DoublyLinkList  *node1;
node1 = create_none_list();

append_node(node1,66);//在链表尾部添加节点
append_node(node1,88);//在链表尾部添加节点

preappend_node(node1,33);//在链表头部添加节点
preappend_node(node1,44);//在链表头部添加节点

print_list_head(node1);//打印链表

//    delete_local_node(node1,3);//删除指定位置的节点
//    delete_head_node(node1);//删除头节点
//    delete_tail_node(node1);//删除尾节点
//    delete_node_by_data(node1 ,33);//根据值删除节点(删除第一个匹配的)
//    delete_list_all(node1);//清空整个链表
//    find_node_by_data(node1,66);//根据data值,查找节点地址
add_node_in_list(node1,3,55);//插入节点到指定位置,eg:position == 2:新节点作为第2个几点 


print_list_head(node1);//打印链表,从头到尾
print_list_tail(node1);//打印一个链表,从尾到头


lease_list_node(node1);//释放链表

}
//实现反转链表功能
//
//实现排序功能
//
//实现合并两个链表的功能
//
//实现循环双链表(尾节点指向头节点)
相关推荐
安科士andxe5 小时前
深入解析|安科士1.25G CWDM SFP光模块核心技术,破解中长距离传输痛点
服务器·网络·5g
YJlio8 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
CTRA王大大8 小时前
【网络】FRP实战之frpc全套配置 - fnos飞牛os内网穿透(全网最通俗易懂)
网络
小白同学_C8 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖8 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
testpassportcn9 小时前
AWS DOP-C02 認證完整解析|AWS DevOps Engineer Professional 考試
网络·学习·改行学it
通信大师9 小时前
深度解析PCC策略计费控制:核心网产品与应用价值
运维·服务器·网络·5g
不做无法实现的梦~10 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
Tony Bai10 小时前
告别 Flaky Tests:Go 官方拟引入 testing/nettest,重塑内存网络测试标准
开发语言·网络·后端·golang·php
消失的旧时光-194311 小时前
从 0 开始理解 RPC —— 后端工程师扫盲版
网络·网络协议·rpc