zoukankan      html  css  js  c++  java
  • C语言实现单链表-03版

    C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式;

    它没有更多的更新功能,因此我们这个版本将要完成如下功能:

    Problem

    1,搜索相关节点;

    2,前插节点;

    3,后追加节点;

    4,一个专门遍历数据的功能;

    Solution

    我们的数据结构体定义如下,和上一个版本稍微有所不同;

    例如,我们把人这个结构体添加一个name域,前几个版本没有名字的节点;

    我们叫起来很尴尬,都是第几个第几个节点,好啦!现在有名字啦!

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct person_ {
        int hight;
        int weight;
        char name[32];
    }Person;
    
    typedef struct node_ {
        Person *data;
        struct node_ * next;
    }Node;
    
    typedef struct link_list_ {
        Node * head;
        Node * tail;
        int size;
    }Link_List;

    和第二版本一样,我们需要创建节点的函数;

    还需要创建链表的函数;

    还有一个插入函数;

    Node * create_node(void *data)
    {
        Node * tmp = (Node*)malloc(sizeof(Node));
        if(tmp) {
            tmp->data = data;
            tmp->next = NULL;
        }
        return tmp;
    }
    
    Link_List * init_list(void)
    {
        Link_List * lst = (Link_List*)malloc(sizeof(Link_List));
        lst->head = lst->tail = NULL;
        lst->size = 0;
        return lst;
    }
    
    void insert(Link_List * lst,void *data)
    {
        Node * new_node = create_node(data);
        if(lst->size == 0) {
            lst->tail = new_node;
        }
        new_node->next = lst->head;
        lst->head = new_node;
        lst->size++;
    }

    好啦!这些函数都没有注释,第一个原因可以认为我很懒;

    第二个原因是可以认为这太简单啦,以至于我们不希望看到多余的注释;

    好啦!我们第三版的第一个函数,遍历输出节点的函数:

    void travel(Link_List * root)
    {
        if(root) {
            Node * we = root->head;
            while(we != NULL) {
                printf("Name:%s--Hight:%d--Weight:%d
    ",we->data->name,we->data->hight,we->data->weight);
                we = we->next;
            }
        }
        return ;
    }

    我们暂时不测试它先,因为要是测试它,我们留着待会一起测试;

    继续,写我们的查找函数,它能够按照给定的名字查找我们的节点哦;

    Node * search_by_name(Link_List * lst, char * name)
    {
        Node * target = lst->head;
        while (target != NULL ){
            if(!strcmp(target->data->name,name)) {
                puts("Found it");
                return target;
            }
            target = target->next;
        }
        puts("Cannot found it");
        return NULL;
    }

    若是找到啦!会提示我们的,并且返回找的的节点;

    当然要是你有同名的节点,它只会把第一个找到得送给你哦;

    (这里考虑一下,要是,第一个找到得不是你期望的哪个,你该怎么实现继续往下查找呢)

    要是找不到目标节点也会提示我们的,并且返回空指针;

    如果成功找到了目标节点,你肯定想看看它长啥样;

    所以我们需要一个函数描述它:

    void node_detail(Node * node)
    {
        if(node) {
            printf("The detail of target node >>Name: %s -- Hight: %d -- Weight: %d
    ",node->data->name,node->data->hight,node->data->weight);
        }
        return ;
    }

    有时候我们找到了目标节点,并不是仅仅想看看它长什么样;

    还想在它之后添加一个节点;

    所以我们需要一个追加函数:

    void append_after(Link_List * lst, Node * new, Node * old) 
    {
        Node * target = lst->head;
        while(target != NULL){
            if(target == old){
                new->next = old->next;
                old->next = new;
                puts("Append successful");
                return ;
            }
            target = target->next;
        }
        return ;
    }

    好啦!哪有时候,我们并不想追加,我们想把一个新节点插入到某个节点之前;

    该怎么做呢?

    注意和前面的追加函数进行对比分析哈!因为他们非常相似;

    void insert_before(Link_List *lst, Node * new, Node * old)
    {
        Node * target = lst->head;
        while(target->next != NULL){
            if(target->next == old){
                new->next = target->next;
                target->next = new;
                puts("Insert successful");
                return ;  
            }             
            target->next = target->next->next;
        }
        return ;
    }

    好啦!又到我们的测试代码部分啦!

    int main(void)
    {
        Link_List * root = init_list();
    
        Person a = { 60, 170, "Frank" };
        Person b = { 70, 180, "Jack" };
        Person c = { 80, 190, "Landpack" };
    
        insert(root,&a);
        insert(root,&b);
        insert(root,&c);
    
        //test travel function 
        travel(root);
    
        return 0;
    }

    测试结果:

    好啦!继续测试搜索查找节点的功能:

    int main(void)
    {
        Link_List * root = init_list();
    
        Person a = { 60, 170, "Frank" };
        Person b = { 70, 180, "Jack" };
        Person c = { 80, 190, "Landpack" };
    
        insert(root,&a);
        insert(root,&b);
        insert(root,&c);
    
        //test travel function 
        travel(root);
    
        // test search node
        Node * result = search_by_name(root,"Jack");
        node_detail(result);
        return 0;
    }

    再看看查找结果,并且顺便看看我们的detail函数是否有效;

    接下来就是追加函数和插入函数的测试啦;

    好啦!首先是追加函数测试;

    int main(void)
    {
        Link_List * root = init_list();
    
        Person a = { 60, 170, "Frank" };
        Person b = { 70, 180, "Jack" };
        Person c = { 80, 190, "Landpack" };
    
        insert(root,&a);
        insert(root,&b);
        insert(root,&c);
    
        //test travel function 
        travel(root);
    
        // test search node
        Node * result = search_by_name(root,"Jack");
        node_detail(result);
    
        // test append function 
        Person d = { 88,180,"Peter" };
        Node * new_d = create_node(&d);
        append_after(root,new_d,result);
        travel(root);
    
        return 0;
    }

    测试结果如下:

    好啦!最后测试我们的插入函数:

    int main(void)
    {
        Link_List * root = init_list();
    
        Person a = { 60, 170, "Frank" };
        Person b = { 70, 180, "Jack" };
        Person c = { 80, 190, "Landpack" };
    
        insert(root,&a);
        insert(root,&b);
        insert(root,&c);
    
        //test travel function 
        travel(root);
    
        // test search node
        Node * result = search_by_name(root,"Jack");
        node_detail(result);
    
        // test append function 
        Person d = { 88,180,"Peter" };
        Node * new_d = create_node(&d);
        append_after(root,new_d,result);
        travel(root);
    
        // test insert function 
        Person e = { 77,170,"Sap" };
        Node * new_e = create_node(&e);
        insert_before(root,new_e,result);
        travel(root);
    
    
        return 0;
    }

    测试结果如下:

    好啦!我们本次版本更新的所有的任务完成啦!

    要是项目经理满意的话会请我们喝啤酒啦!

    所有代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct person_ {
        int hight;
        int weight;
        char name[32];
    }Person;
    
    typedef struct node_ {
        Person *data;
        struct node_ * next;
    }Node;
    
    typedef struct link_list_ {
        Node * head;
        Node * tail;
        int size;
    }Link_List;
    
    Node * create_node(void *data)
    {
        Node * tmp = (Node*)malloc(sizeof(Node));
        if(tmp) {
            tmp->data = data;
            tmp->next = NULL;
        }
        return tmp;
    }
    
    Link_List * init_list(void)
    {
        Link_List * lst = (Link_List*)malloc(sizeof(Link_List));
        lst->head = lst->tail = NULL;
        lst->size = 0;
        return lst;
    }
    
    void insert(Link_List * lst,void *data)
    {
        Node * new_node = create_node(data);
        if(lst->size == 0) {
            lst->tail = new_node;
        }
        new_node->next = lst->head;
        lst->head = new_node;
        lst->size++;
    }
    void travel(Link_List * root)
    {
        if(root) {
            Node * we = root->head;
            while(we != NULL) {
                printf("Name:%s--Hight:%d--Weight:%d
    ",we->data->name,we->data->hight,we->data->weight);
                we = we->next;
            }
        }
        return ;
    }
    
    
    Node * search_by_name(Link_List * lst, char * name)
    {
        Node * target = lst->head;
        while (target != NULL ){
            if(!strcmp(target->data->name,name)) {
                puts("Found it");
                return target;
            }
            target = target->next;
        }
        puts("Cannot found it");
        return NULL;
    }
    
    void node_detail(Node * node)
    {
        if(node) {
            printf("The detail of target node >>Name: %s -- Hight: %d -- Weight: %d
    ",node->data->name,node->data->hight,node->data->weight);
        }
        return ;
    }
    
    void append_after(Link_List * lst, Node * new,Node * old)
    {
        Node * target = lst->head;
        while(target != NULL){
            if(target == old){
                new->next = old->next;
                old->next = new;
                puts("Append successful");
                return ;
            }
            target = target->next;
        }
        return ;
    }
    void insert_before(Link_List *lst, Node * new, Node * old)
    {
        Node * target = lst->head;
        while(target->next != NULL){
            if(target->next == old){
                new->next = target->next;
                target->next = new;
                puts("Insert successful");
                return ;
            }
            target->next = target->next->next;
        }
        return ;
    }
    
    int main(void)
    {
        Link_List * root = init_list();
    
        Person a = { 60, 170, "Frank" };
        Person b = { 70, 180, "Jack" };
        Person c = { 80, 190, "Landpack" };
    
        insert(root,&a);
        insert(root,&b);
        insert(root,&c);
    
        //test travel function 
        travel(root);
    
        // test search node
        Node * result = search_by_name(root,"Jack");
        node_detail(result);
    
        // test append function 
        Person d = { 88,180,"Peter" };
        Node * new_d = create_node(&d);
        append_after(root,new_d,result);
        travel(root);
    
        // test insert function 
        Person e = { 77,170,"Sap" };
        Node * new_e = create_node(&e);
        insert_before(root,new_e,result);
        travel(root);
    
    
        return 0;
    }

    Discussion

    我们的链表似乎挺棒啦!但是烦人的项目经理是不会满足的;

    他说下次版本更新,最好添加一个删除节点的功能;

    (因为他可能想解聘一些员工啦!希望不会是我哦)

    还有。。。。

    他说反正有很大任务的。。。。

    哈哈下次见;

     

    Can we drop this masquerade
  • 相关阅读:
    【BZOJ-4031】小z的房间 Matrix-Tree定理 + 高斯消元解行列式
    无题
    【BZOJ-4261】建设游乐场 最大费用最大流
    【BZOJ-2888】资源运输 LCT + 启发式合并
    【Codeforces666E】Forensic Examination 后缀自动机 + 线段树合并
    【BZOJ-2142】礼物 拓展Lucas定理
    【BZOJ-3672】购票 树分治 + 斜率优化DP
    【BZOJ-3218】a+b Problem 最小割 + 可持久化线段树
    【BZOJ-1913】signaling信号覆盖 极角排序 + 组合
    【BZOJ-4408】神秘数 可持久化线段树
  • 原文地址:https://www.cnblogs.com/landpack/p/4815676.html
Copyright © 2011-2022 走看看