C 语言链表

用 c 语言把链表的基本操作实现了一遍,节点数据的信息是「编号」、「姓名」和「年龄」,实现的功能有「链表的创建」「链表初始化」、「插入节点」、「链表的遍历」、「链表的销毁」、「查询节点」、「删除节点」,这里我就把这些函数贴在这里,做一个笔记,以后也可以查看。

定义数据结构:

typedef struct Person {
    int number;
    char name[50];
    int age;
} Person_t;

typedef struct MLGB {
    Person_t monster;
    struct MLGB *next;
} MLGB_t;

typedef struct LinkList {
    MLGB_t *head;
    MLGB_t *tail;
    int len;
} LinkList_t;

链表的初始化:

/*
   初始化链表
   */
void init_link_list(LinkList_t *nnd) {
    nnd->head = NULL;
    nnd->tail = NULL;
    nnd->len = 0;

    return;
}

插入节点:

(一)、头部插入

  /*
  成功返回 0
   失败返回 -1
   */
int insert_node_head(MLGB_t *cnm, LinkList_t *nnd) {
    if (cnm == NULL || nnd == NULL) {
        perror("空链表..\n");
        return -1;
    }
    if (nnd->head == NULL) {
        // 当前链表为空
        nnd->head = cnm;
        nnd->tail = cnm;
        cnm->next = NULL;

        nnd->len = 1;

        return 0;
    } else {
        // 当前链表不为空
        cnm->next = nnd->head;
        nnd->head = cnm;
        nnd->len++;

        return 0;
    }

    return 0;
}

(二)、尾部插入


/*
   尾部,节点插入
   成功返回 0 ;失败返回 -1
   */

int insert_node_tail(MLGB_t *cnm, LinkList_t *nnd) {
    if (cnm == NULL || nnd == NULL) {
        perror("NULL 指针..\n");
        return -1;
    }
    if (nnd->head == NULL) { // 链表为空
        nnd->head = cnm;
        nnd->tail = cnm;
        cnm->next = NULL;
        nnd->len = 1;
        return 0;
    } else {
        nnd->tail->next = cnm;
        nnd->tail = cnm;
        cnm->next = NULL;
        nnd->len++;

        return 0;
    }

    return 0;
}

链表的遍历:

/*
   遍历链表
   返回链表的长度
   */
int show_link_list(LinkList_t *nnd) {
    if (nnd->len == 0) {
        printf("空链表。。\n");
    }


    MLGB_t *temp = NULL;
    temp = nnd->head;

    while (temp != NULL) {
        printf("编号(number): %d\t姓名(name): %s\t年龄(age): %d\n",
                temp->monster.number, temp->monster.name, temp->monster.age);
        temp = temp->next;
    }

    return nnd->len;
}

销毁一个链表:

/*
   销毁一个链表, 释放每个节点的内存,同时初始化链表为空
   成功返回 0 ,失败返回 -1
   */
int destroy_linklist(LinkList_t *nnd) {
    MLGB_t *current_p = NULL;
    MLGB_t *temp_p = NULL;

    current_p = nnd->head;

    while (current_p != NULL) { // 删除当前节点
        temp_p = current_p;
        current_p = current_p->next;
        free(temp_p);
    }
    init_link_list(nnd);

    return 0;
}

查找一个节点:


/*
   通过编号(number)查找节点
   成功返回节点的地址
   失败返回 NULL
   */

MLGB_t * query_node_by_number(LinkList_t *nnd, int number1) {
    MLGB_t *current_p = NULL;
    current_p = nnd->head;

    while (current_p != NULL) {
        if (current_p->monster.number == number1) {
            // 找到节点
            return current_p;
        }
        current_p = current_p->next;
    }

    return NULL;
}

删除一个节点:


/*
   通过名字删除一个节点
   成功返回 0
   失败返回 -1

 *node_point_del 用来保存被删除节点的地址
 */

int delete_by_name(LinkList_t *nnd, char *name1,
        MLGB_t **node_point_del) {
    MLGB_t *current_p = NULL; // 用来保存当前节点
    MLGB_t *pre_p = NULL; // 用来保存前驱地址

    current_p = nnd->head;
    // 找节点
    while (current_p != NULL) {
        if (strcmp(current_p->monster.name, name1) == 0) {
            if (current_p == nnd->head) {
                // 要是删除的是头结点
                nnd->head = nnd->head->next;
                *node_point_del = current_p;
            } else if (current_p == nnd->tail) {
                // 如果是尾节点
                nnd->tail = pre_p; // 指向前驱
                pre_p = NULL;
                *node_point_del = current_p;
            } else {
                pre_p->next = current_p->next;
                *node_point_del = current_p;
            }
            nnd->len--;

            return 0;
        }

        pre_p = current_p; // 记下 current_p 的前驱
        current_p = current_p->next;
    }
    printf("没能找到 %s 的信息..\n", name1);
    *node_point_del = NULL;

    return -1;
}

程序运行:

写个主程序测试一些功能,功能都实现了。

程序运行测试结果

posted @   double64  阅读(241)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示