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\n",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\n",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\n",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\n",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

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

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

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

还有。。。。

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

哈哈下次见;

时间: 2024-07-30 13:44:44

C语言实现单链表-03版的相关文章

C语言实现单链表-02版

我们在C语言实现单链表-01版中实现的链表非常简单: 但是它对于理解单链表是非常有帮助的,至少我就是这样认为的: 简单的不能再简单的东西没那么实用,所以我们接下来要大规模的修改啦: Problem 1,要是数据很多怎么办,100000个节点,这个main函数得写多长啊... 2,这个连接的方式也太土啦吧!万一某个节点忘记连接下一个怎么办... 3,要是我想知道这个节点到底有多长,难道每次都要从头到尾数一遍嘛... 4,要是我想在尾部添加一个节点,是不是爬也要爬到尾部去啊... 这个是简单版中提出

C语言实现单链表-04版

前面的版本似乎没能让项目经理满意,他还希望这个链表有更多的功能: 我们接下来要解决几个比较简单的功能: Problem 1,更加友好的显示数据: 2,能够通过名字删除节点: Solution 首先我们编写一个简单的提示信息的函数: void when(char * tips){ time_t rawtime; struct tm* timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); char * timestr = ascti

C语言实现单链表节点的删除(带头结点)

我在之前一篇博客<C语言实现单链表节点的删除(不带头结点)>中具体实现了怎样在一个不带头结点的单链表的删除一个节点,在这一篇博客中我改成了带头结点的单链表.代码演示样例上传至 https://github.com/chenyufeng1991/DeleteLinkedList_HeadNode.删除类型有两种: (1)删除某个位置pos的节点: (2)推断x值是否在链表中,若存在则删除该节点: 核心代码例如以下: //删除某个位置pos的节点 Node *DeletePosNode(Node

C语言实现单链表的节点插入(带头结点)

我在之前一篇博客<C语言实现单链表(不带头结点)节点的插入>中具体实现了怎样在一个不带头结点的单链表中进行节点的插入.可是在实际应用中,带头结点的链表更为经常使用.更为方便.今天我们就要来使用带头结点的单链表进行节点的插入.演示样例代码上传至 https://github.com/chenyufeng1991/InsertList_HeadNode  . 核心代码例如以下: Node *InsertNode(Node *pNode,int pos,int x){ int i = 0; Node

C语言实现单链表(带头结点)的基本操作

我在之前一篇博客<C语言实现单链表(不带头结点)的基本操作>中具体实现了不带头结点的单链表的11种操作:如计算链表长度.初始化.创建链表.清空链表等等.但是在实际使用中,带头结点的单链表往往比不带头结点的单链表用的更多,使用也更为方便.因为不用单独考虑第一个节点的情况了,第一个节点和其他后续节点的处理全都一样了,简化操作.这篇博客将会来实现带头结点的单链表的11种操作.代码上传至: https://github.com/chenyufeng1991/LinkedList_HeadNode  .

「C语言」单链表/双向链表的建立/遍历/插入/删除

最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合,一种面向过程的MVC的感觉. 而这一切的基础就在于对链表的创建.删除.输出.写入文件.从文件读出...... 本篇文章在于巩固链表的基础知识(整理自<C语言程序设计教程--人民邮电出版社>第十章),只对链表的概念及增删改查作出探讨,欢迎指教. 一.链表结构和静态/动态链表 二.单链表的建立与遍历

【c语言】 单链表

单链表,顾名思义是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素. 链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据. 我们在这里使用C语言实现: .h 文件: #pragma once #include<assert.h> #include <malloc.h> typedef int DataType; typedef struct SLis

C语言实现单链表(不带头结点)节点的插入

对单链表进行增删改查是最主要的操作.我在上一篇博客<C语言实现链表节点的删除>实现了删除单链表中的某个节点. 这里我们要来实如今某个位置插入节点.演示样例代码上传至https://github.com/chenyufeng1991/InsertList  . 核心代码例如以下: Node *InsertToPosition(Node *pNode,int pos,int x){ if (pos < 0 || pos > sizeList(pNode) ) { printf(&quo

一起talk C栗子吧(第十三回:C语言实例--单链表二)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是链表以及单链表顺序储存方式的例子,这一回咱们继续说单链表的例子,不 过这一回咱们说的是:单链表链式存储. 看官们单链表的链式存储,咱们在上一回已经说过,这里就不再多说了.这一回主要举例子,通过例子来 说明什么是单链表的链式存储. 通过对比单链表的顺序储存和链式存储,可以看出来. 顺序存储链表的优点:遍历链表方便,查找也方便. 顺序存