在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
我们的链表似乎挺棒啦!但是烦人的项目经理是不会满足的;
他说下次版本更新,最好添加一个删除节点的功能;
(因为他可能想解聘一些员工啦!希望不会是我哦)
还有。。。。
他说反正有很大任务的。。。。
哈哈下次见;