我们在C语言实现单链表-01版中实现的链表非常简单;

但是它对于理解单链表是非常有帮助的,至少我就是这样认为的;

简单的不能再简单的东西没那么实用,所以我们接下来要大规模的修改啦;

Problem

1,要是数据很多怎么办,100000个节点,这个main函数得写多长啊。。。

2,这个连接的方式也太土啦吧!万一某个节点忘记连接下一个怎么办。。。

3,要是我想知道这个节点到底有多长,难道每次都要从头到尾数一遍嘛。。。

4,要是我想在尾部添加一个节点,是不是爬也要爬到尾部去啊。。。

这个是简单版中提出的问题,接下来就解决它们;

Solution

首先,定义我们的数据域,它既然是一个人,那么就把身高和体重放到人身上吧;

  1. typedef struct person_ {
  2. int hight;
  3. int weight;
  4. }Person;

再继续定义我们的节点;

  1. typedef struct node_ {
  2. Person * data;
  3. struct node_ * next;
  4. }Node;

好啦!接下来我们希望有一个函数帮我们把节点连接起来,并且把数据域(人得身高体重)填入;

  1. Node * create_node(void *data)
  2. {
  3. Node * tmp = (Node*)malloc(sizeof(Node));
  4. if(tmp) {
  5. tmp->data = data;
  6. tmp->next = NULL;
  7. }
  8. return tmp;
  9. }

它的意图很明显,只要给我一个人的身高和体重我就返回一个节点给你;

我们到这里可以先测试一下自己的程序看看有什么问题没,然后再继续;

  1. int main(void)
  2. {
  3. Person a = { , };
  4. Node * A = create_node(&a);
  5.  
  6. Person b = { , };
  7. Node * B = create_node(&b);
  8.  
  9. Person c = { , };
  10. Node * C = create_node(&c);
  11.  
  12. A->next = B;
  13. B->next = C;
  14.  
  15. Node * we=NULL;
  16. we = A;
  17.  
  18. while(we != NULL) {
  19. printf("%d--%d\n",we->data->hight,we->data->weight);
  20. we = we->next;
  21. }
  22. return ;
  23. }

看看结果:

似乎比前一个版本有所进步;

但是可以怎么说,链表的内脏我们写进去啦!但是它的肠子还露在外边,恶心吧:);

如果不能,理解的话,你请看在main函数中那些恶心的步骤任然在。。。;

好吧!解决它;

  1. typedef struct link_list_ {
  2. Node * head;
  3. Node * tail;
  4. int size;
  5. }Link_List;

为了更好的管理我们的链表,我们需要知道它的头和尾还有它到底有多长;

因此,上面的结构体应该是暂时可以这么写的;

好吧!有了结构体,接下来就是初始化它啦!它就像其他int,char类型一样使用前一样需要初始化;

(就像哪个婴儿都喜欢喝奶一样哈)

  1. Link_List * init_list(void)
  2. {
  3. Link_List * lst = (Link_List*)malloc(sizeof(Link_List));
  4. lst->head = lst->tail = NULL;
  5. lst->size = ;
  6. return lst;
  7. }

初始化后,我们需要给它添加一些节点啦;

这里链表的管理的方式很简单,它只记住链表的头和尾还有长度,不关心你在里面存入什么数据;

(就好比,学校的宿舍管理员,它只知道拿着宿舍大门的钥匙,才不管你在宿舍里怎么睡觉---其实有些管得很严呢:);

好啦!我们需要一个插入节点的函数(让我们的肠子跟随内脏一起进去吧,不要再继续恶心啦

我们的插入数据函数如下:

  1. void insert(Link_List *lst,void *data)
  2. {
  3. Node * new_node = create_node(data);
  4. if(lst->size == ) {
  5. lst->tail = new_node; //tip:01
  6. }
  7.  
  8. new_node->next=lst->head;
  9. lst->head = new_node;
  10. lst->size++;
  11. }

然后可以测试我们的代码啦!

  1. int main(void)
  2. {
  3. Link_List * root = init_list();
  4.  
  5. Person a = { , };
  6. Person b = { , };
  7. Person c = { , };
  8.  
  9. insert(root,&a);
  10. insert(root,&b);
  11. insert(root,&c);
  12.  
  13. Node * we=NULL;
  14. we = root->head;
  15.  
  16. while(we != NULL) {
  17. printf("%d--%d\n",we->data->hight,we->data->weight);
  18. we = we->next;
  19. }
  20. return ;
  21. }

看看结果:

注意看,我们的输出次序与前面的次序不一样啦!

怎么回事呢?思考一下会;

这个问题先不告诉大家,接下来看看我们的链表是不是管理正常;

首先,看看这个链表现在到底它到底有多长呢;

  1. {
  2. Link_List * root = init_list();
  3.  
  4. Person a = { , };
  5. Person b = { , };
  6. Person c = { , };
  7.  
  8. insert(root,&a);
  9. insert(root,&b);
  10. insert(root,&c);
  11.  
  12. Node * we=NULL;
  13. we = root->head;
  14.  
  15. while(we != NULL) {
  16. printf("%d--%d\n",we->data->hight,we->data->weight);
  17. we = we->next;
  18. }
  19. printf("The size of the link-list is : %d\n",root->size);
  20. return ;
  21. }

看看结果:

再看看,尾部和头部节点,是不是都能很轻松的告诉我们呢;

  1.   printf("The size of the link-list is : %d\n",root->size);
  2. printf("The head guy is %d--%d\n",root->head->data->hight,root->head->data->weight);
  3. printf("The last guy is %d--%d\n",root->tail->data->hight,root->tail->data->weight);
  4. return ;

好啦!再看结果:

好啦!结果正如我们期待的;

观察发现,我们的最后两句是root->head->data->hight等等,非常长,这里给大家介绍一种简单的写法;

  1. #define GO_H(RT,HW) (RT->head->data->HW) //GO_H:go head; RT:Root; HW: Hight,Weight
  2. #define GO_T(RT,HW) (RT->tail->data->HW) //GO_T:go tail; RT :Root; HW: Hight,Weight

然后我们的代码就可以这样写啦!

  1. printf("The head guy is %d--%d\n",GO_H(root,hight),GO_H(root,weight));
  2. printf("The last guy is %d--%d\n",GO_T(root,hight),GO_T(root,weight));

好啦!基本上完成啦!

所有代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define GO_H(RT,HW) (RT->head->data->HW) //GO_H:go head; RT:Root; HW: Hight,Weight
  5. #define GO_T(RT,HW) (RT->tail->data->HW) //GO_T:go tail; RT :Root; HW: Hight,Weight
  6.  
  7. typedef struct person_ {
  8. int hight;
  9. int weight;
  10. }Person;
  11.  
  12. typedef struct node_ {
  13. Person * data;
  14. struct node_ * next;
  15. }Node;
  16.  
  17. typedef struct link_list_ {
  18. Node * head;
  19. Node * tail;
  20. int size;
  21. }Link_List;
  22.  
  23. Node * create_node(void *data)
  24. {
  25. Node * tmp = (Node*)malloc(sizeof(Node));
  26. if(tmp) {
  27. tmp->data = data;
  28. tmp->next = NULL;
  29. }
  30. return tmp;
  31. }
  32.  
  33. Link_List * init_list(void)
  34. {
  35. Link_List * lst = (Link_List*)malloc(sizeof(Link_List));
  36. lst->head = lst->tail= NULL;
  37. lst->size = ;
  38. return lst;
  39. }
  40. void insert(Link_List *lst,void *data)
  41. {
  42. Node * new_node = create_node(data);
  43. if(lst->size == ) {
  44. lst->tail = new_node; //tip:01
  45. }
  46.  
  47. new_node->next=lst->head;
  48. lst->head = new_node;
  49. lst->size++;
  50. }
  51. int main(void)
  52. {
  53. Link_List * root = init_list();
  54.  
  55. Person a = { , };
  56. Person b = { , };
  57. Person c = { , };
  58.  
  59. insert(root,&a);
  60. insert(root,&b);
  61. insert(root,&c);
  62.  
  63. Node * we=NULL;
  64. we = root->head;
  65.  
  66. while(we != NULL) {
  67. printf("%d--%d\n",we->data->hight,we->data->weight);
  68. we = we->next;
  69. }
  70. printf("The size of the link-list is : %d\n",root->size);
  71. printf("The head guy is %d--%d\n",GO_H(root,hight),GO_H(root,weight));
  72. printf("The last guy is %d--%d\n",GO_T(root,hight),GO_T(root,weight));
  73. return ;
  74. }

但是我不得不告诉你,它还有很多缺陷;

我们下次再讨论;

C语言实现单链表-02版的更多相关文章

  1. C语言实现单链表-03版

    在C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式: 它没有更多的更新功能,因此我们这个版本将要完成如下功能: Problem 1,搜索相关节点: 2,前插节点: 3,后追加节点: 4, ...

  2. C语言实现单链表-01版

    单链表的应用非常广,它可以实现栈,队列等: Problem 我对学习任何东西都希望能找到尽可能简单的例子,而不是看起来好高大上的: 对链表这样简答的数据结构,有些书也是写得太过“完美”啦: 初学者很难 ...

  3. C语言实现单链表-04版

    前面的版本似乎没能让项目经理满意,他还希望这个链表有更多的功能: 我们接下来要解决几个比较简单的功能: Problem 1,更加友好的显示数据: 2,能够通过名字删除节点: Solution 首先我们 ...

  4. C语言实现单链表,并完成链表常用API函数

    C语言实现单链表,并完成链表常用API函数: 1.链表增.删.改.查. 2.打印链表.反转打印.打印环形链表. 3.链表排序.链表冒泡排序.链表快速排序. 4.求链表节点个数(普通方法.递归方法). ...

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

    我在之前一篇博客<C语言实现单链表节点的删除(不带头结点)>中具体实现了怎样在一个不带头结点的单链表的删除一个节点,在这一篇博客中我改成了带头结点的单链表.代码演示样例上传至 https: ...

  6. C/C++语言实现单链表(带头结点)

    彻底理解链表中为何使用二级指针或者一级指针的引用 数据结构之链表-链表实现及常用操作(C++篇) C语言实现单链表,主要功能为空链表创建,链表初始化(头插法),链表元素读取,按位置插入,(有序链表)按 ...

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

    最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合, ...

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

    各位看官们,大家好.从今天開始,我们讲大型章回体科技小说 :C栗子.也就是C语言实例.闲话休提, 言归正转. 让我们一起talk C栗子吧! 看官们,上一回中咱们没有说详细的样例,并且是说了样例中的文 ...

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

    对单链表进行增删改查是最主要的操作.我在上一篇博客<C语言实现链表节点的删除>实现了删除单链表中的某个节点. 这里我们要来实如今某个位置插入节点.演示样例代码上传至https://gith ...

随机推荐

  1. Oracle SQL优化一(常见方法)

    1.表访问方式优化: a)普通表优先“Index Lookup 索引扫描”,避免全表扫描 大多数场景下,通过“Index Lookup 索引扫描”要比“Full Table Scan (FTS) 全表 ...

  2. hibernate学习(设计一对多 关系 映射)

    1,配置文件: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-conf ...

  3. zookeeper client 常用操作

    #获取权限(类似于登陆) addauth digest admin-user:admin-password #查看权限 getAcl /collections/meixin_product/state ...

  4. SAP 打开账期

    1.先OB52修改账期: 如下界面开得公司9000下面 7.8月份的账期 2.mmpv 关闭上两个账期 3.mmrv 查看现在账期情况

  5. HttpServletrequest 与HttpServletResponse总结

    如果说DOM是javascript与HTML的桥梁,那么servlet就是前端与后端的桥梁,HttpServletRequest和HttpServletResponse就是之间的信使,好了,废话不多说 ...

  6. github的一些指令

  7. 华为手机打开Logcat的方法

    华为手机默认是关闭logcat信息的,这在开发调试时当然很不方便,打开log信息的方法如下 1. 进入拨号界面输入:*#*#2846579#*#*  2. 依次选择ProjectMenu---后台设置 ...

  8. 小希的数表2(用的for循环)

    #include<iostream> 02.#include<algorithm> 03.using namespace std; 04. 05.bool cmp(int a, ...

  9. JDBC常用接口详解

    JDBC中常用接口详解 ***DriverManager 第一.注册驱动 第一种方式:DriverManager.registerDriver(new com.mysql.jdbc.Driver()) ...

  10. jQueryEasyUI

    jQueryEasyUI 编辑 jQuery EasyUI是一组基于jQuery的UI插件集合体,而jQuery EasyUI的目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面.开发者 ...