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

}
//实现反转链表功能
//
//实现排序功能
//
//实现合并两个链表的功能
//
//实现循环双链表(尾节点指向头节点)
相关推荐
0xDevNull10 小时前
Linux切换JDK版本详细教程
linux
进击的丸子10 小时前
虹软人脸服务器版SDK(Linux/ARM Pro)多线程调用及性能优化
linux·数据库·后端
Johny_Zhao2 天前
OpenClaw安装部署教程
linux·人工智能·ai·云计算·系统运维·openclaw
chlk1233 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑3 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件3 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
深紫色的三北六号4 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash4 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI4 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行5 天前
Linux和window共享文件夹
linux