这节开始整理韩顺平的“单链表”公开课笔记,为了代码更规范更有结构,有些地方楠神会做改动。网上可以搜到他的视频《韩顺平一周玩转算法》:
使用head头的单向链表实现——水浒英雄排行榜管理
首先定义“英雄”类:
了解单链表先要弄懂内存分析图:
PHP的底层是c,当一个程序运行的时候,内存分成五个区[栈区/堆区/全局区/常量区/代码区]
每一个对象实例都是在堆区分布的,所以单链表的数据都是分散存于堆区的。
定义一个显示英雄的函数:
我们在显示文件linklist.php实例化两个对象写入链表:
用函数show_heros显示链表里的英雄:
把添加英雄的代码打包成一个函数:
换成add_hero函数添加英雄
按照英雄的排行加入(这里我希望能够保证链表的顺序)
以后参加工作的时候,有可能会有这样的需求,别人给你一堆字符串,让你按照字符串的某一个属性进行排序,而且是在内存中完成排序。
怎样按照顺序来添加呢?
★一定要先谈思路,再写代码。分析图:
思路分析:
(1)先加1号人物,首先cur指向head节点,cur->next为空,直接把1号人物加在head节点后面;
(2)再加2号人物,首先cur指向head节点,cur->next此时指向1号人物节点,cur->next->no为1和$hero->no为2进行比较,发现1不大于2,所以cur就向下面走一步,此时cur指向了1号人物节点,然后再去判断cur->next->no是否大于2,因为此时cur->next为空了,没法走了,只能把2号人物加在1号人物节点的后面。
(3)再加6号人物,首先cur指向head节点,cur->next此时指向1号人物节点,cur->next->no为1和$hero->next为6进行比较,发现1不大于6,所以cur就向下面走一步,此时cur指向1号人物节点,然后再去判断cur->next->no为2和$hero->no为6进行比较,发现2不大于6,所以cur就向下面走一步,此时cur指向了2号人物节点,然后再去判断cur->next->no是否大于6,因为此时cur->next为空了,没法走了,只能把6号人物加在2号人物节点的后面。
(4)再加3号人物,首先cur指向head节点,cur->next此时指向1号人物节点,cur->next->no为1和$hero->next为3进行比较,发现1不大于3,所以cur就向下面走一步,此时cur指向1号人物节点,然后再去判断cur->next->no为2和$hero->no为3进行比较,发现2不大于3,所以cur就向下面走一步,此时cur指向了2号人物节点,然后再去判断cur->next->no为6和$hero->no为3进行比较,发现6大于3,找到位置了,通过一种操作想办法把3号人物加进去。
改进下添加英雄函数:
添加数据顺序不变,“林冲”在“吴用”的前面,但排序却变化了。
如上图所示,当加入3号人物的时候,cur指向2号人物节点,cur->next指向地址0x1234,即是6号人物节点,此时3号人物的地址为0x345。执行$hero->next=$cur->next;即让3号人物的节点的next指向6号人物节点地址0x1234,图中的①虚蓝线所示;然后$cur->next=$hero;即把2号人物节点的next由指向地址0x1234改为指向3号人物节点地址0x345,图中的③虚蓝线所示,原来的②实线断开。
这样就把3号人物插在了2号人物的后面。
添加英雄的函数还是不够完美,改进功能,不让有相同排名的英雄加入链表。
添加重复的英雄进去:
看结果:
没有好办法,光看是学不会的,自己动手敲代码,自己画图分析,加深理解。