单链表各种操作实现(数据结构C语言多文件编写)

发布于:2025-04-16 ⋅ 阅读:(17) ⋅ 点赞:(0)

1.先创建list.h声明文件( Linux 命令:touch list.h)。编写函数声明如下(打开文件 Linux 操作命令:vim list.h):

//链表头文件
#ifndef __LIST_H__
#define __LIST_H__
//节点
typedef struct node{
    int data;//数据
    struct node* next;//下个节点地址
}node_t;

//链表
typedef struct list{
    node_t* head;//记录头结点地址
    node_t* tail;//记录尾节点地址
}list_t;

//链表初始化
void list_init(list_t* l);
//链表的释放
void list_deinit(list_t* l);
//头部插入节点
void list_insert_head(list_t* l,int data);
//尾部插入节点
void list_insert_tail(list_t* l,int data);
//链表顺序插入
void list_insert(list_t* l,int data);
//删除节点
void list_del(list_t* l,int data);
//链表的遍历
void list_travel(list_t* l);
#endif //__LIST_H__

2.创建函数实现文件list.c( Linux 命令:touch list.c)。写入函数到文件中:

//链表实现
#include<stdio.h>
#include"list.h"
#include<stdlib.h>

//链表的初始化

void list_init(list_t* l){
    //创建头结点,地址存入head指针
    l->head=malloc(sizeof(node_t));
    //创建尾节点,地址存入tail指针
    l->tail=malloc(sizeof(node_t));
    //讲0存入头尾节点
    l->head->data=0;
    l->tail->data=0;
    
    //头尾节点相连
    l->head->next=l->tail;
    l->tail->next=NULL;
}

//链表的释放
void list_deinit(list_t* l){
    node_t* pnode=l->head;
    while(pnode){
        //tmp 存储下个节点的地址
        node_t* tmp=pnode->next;
        //释放pnode指向的节点
        free(pnode);
        //pnode指向下一个节点
        pnode=tmp;
    }
    l->head=NULL;
    l->tail=NULL;
}
//头部插入
void list_insert_head(list_t* l,int data){
    //准备新节点
    node_t* new=malloc(sizeof(node_t));
    new->data=data;
    new->next=NULL;
    //将新节点插入到节点之后
    //将第一个有效节点的地址 存入 新节点的next 指针
    new->next=l->head->next;
    //将新节点的地址 存入 头结点的 next指针
    l->head->next=new;
}
//尾部插入
void list_insert_tail(list_t* l,int data){
    //准备新节点
    node_t* new= malloc(sizeof(node_t));
        
    new->data=data;
    new->next=NULL;

    for(node_t *p=l->head;p!=l->tail;p->next){
        node_t* first=p;
        node_t* mid=first->next;

        if(mid==l->tail){
            //当mid指向尾节点
            //first 指向最后有效节点
            //新节点插入在 firat和mid指向的节点之间
            //将新节点的地址 存入 first指向节点的next指针
            first->next=new;
            //将尾节点的地址存入
            new->next=mid;
            break;
        }
    }
}
//顺序插入
void list_insert(list_t* l,int data){
    //准备新节点
    node_t* new=malloc(sizeof(node_t));
    new->data=data;
    new->next=NULL;
    //确定位置并插入新节点
    for(node_t* p=l->head;p!=l->tail;p=p->next){
        node_t* first=p;
        node_t* mid=first->next;

        //当mid指向的节点,第一次比新节点大
        //或者mid指向尾节点说明节点最大
        //新节点则应该插入在first和mid指向的节点中间
        if(mid->data>new->data||mid==l->tail){
            //将新节点的地址存入first指向节点的next指针中
            first->next=new;
            //将mid指向节点的地址存入新节点的next指针中
            new->next=mid;
            break;
        }
    }
}
//删除节点
void list_del(list_t* l,int data){
    node_t* first;
    node_t* mid;
    node_t* last;
    for(node_t* p=l->head;p!=l->tail;p=p->next){
        first=p;
        mid=first->next;
        last=mid->next;
        if(mid->data==data){
            first->next=last;
            free(mid);
            break;
        }
    }
    if(mid ==l->tail){
        printf("节点不存在\n");
    }
}
//链表的遍历
void list_travel(list_t* l){
    for(node_t* p=l->head->next;p!=l->tail;p=p->next){
        printf("%d ",p->data);
    }
    printf("\n");
}

3.编写主函数调用文件main.c(Linux命令:touch main.c)。编写逻辑操作:

//链表的实现
#include<stdio.h>
#include"list.h"
int main(void){
    //链表
    list_t list;
    printf("初始化\n");
    list_init(&list);
    printf("头部插入节点\n");
    list_insert_head(&list,30);
    list_insert_head(&list,20);
    list_insert_head(&list,20);
    printf("尾部插入节点\n");
    list_insert(&list,70);
    list_insert(&list,40);
    list_insert(&list,90);
    list_insert(&list,50);
    list_insert(&list,110);
    printf("遍历\n");
    list_travel(&list);
    printf("释放链表\n");
    list_deinit(&list);
    return 0;
}

4.编译运行

Linux命令:gcc main.c list.c -o list

                运行:./list


网站公告

今日签到

点亮在社区的每一天
去签到