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);//释放链表

}
//实现反转链表功能
//
//实现排序功能
//
//实现合并两个链表的功能
//
//实现循环双链表(尾节点指向头节点)
相关推荐
white-persist1 小时前
【vulhub shiro 漏洞复现】vulhub shiro CVE-2016-4437 Shiro反序列化漏洞复现详细分析解释
运维·服务器·网络·python·算法·安全·web安全
黄俊懿1 小时前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第一节:DNS优化
网络·计算机网络·架构·系统架构·cdn·dns·架构设计
代码中介商2 小时前
手把手教你Linux 打包压缩与 gcc 编译详解
linux·运维·服务器·编译·打包·压缩
longerxin20202 小时前
阿里云AlmaLinux操作系统允许root登录配置步骤
linux·服务器·阿里云
独小乐2 小时前
019.ADC转换和子中断|千篇笔记实现嵌入式全栈/裸机篇
linux·c语言·驱动开发·笔记·嵌入式硬件·mcu·arm
Byron Loong2 小时前
【网络】Python 怎么做TCP通讯
网络·python·tcp/ip
GottdesKrieges3 小时前
OceanBase租户级物理恢复
linux·oceanbase
2601_949817723 小时前
基础篇:Linux安装redis教程(详细)
linux·运维·redis
裕工实验室3 小时前
功率模块为什么一定要用陶瓷PCB?从结构到选材一篇讲清(附DPC / DBC / AMB选型逻辑)
网络·硬件工程·pcb工艺·材料工程
CQU_JIAKE3 小时前
4.17[Q]
java·linux·服务器