第八章:第4节 PHP数据结构与算法——单链表强化学习一(遍历、增加功能)

更新于:2017-06-21 21:45:15

这节开始整理韩顺平的“单链表”公开课笔记,为了代码更规范更有结构,有些地方楠神会做改动。网上可以搜到他的视频《韩顺平一周玩转算法》:


使用head头的单向链表实现——水浒英雄排行榜管理

1355372439_5252.jpg


首先定义“英雄”类:


1.png

了解单链表先要弄懂内存分析图:

1355372439_5252.jpg

PHP的底层是c,当一个程序运行的时候,内存分成五个区[栈区/堆区/全局区/常量区/代码区]
每一个对象实例都是在堆区分布的,所以单链表的数据都是分散存于堆区的。


定义一个显示英雄的函数:

1.png


我们在显示文件linklist.php实例化两个对象写入链表:


1.png


用函数show_heros显示链表里的英雄:


1.png

把添加英雄的代码打包成一个函数:

1.png

换成add_hero函数添加英雄

1.png

1.png

按照英雄的排行加入(这里我希望能够保证链表的顺序)


以后参加工作的时候,有可能会有这样的需求,别人给你一堆字符串,让你按照字符串的某一个属性进行排序,而且是在内存中完成排序。
怎样按照顺序来添加呢?


★一定要先谈思路,再写代码。分析图:


1355372439_5252.jpg


思路分析:


(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号人物加进去。


改进下添加英雄函数:

1.png

添加数据顺序不变,“林冲”在“吴用”的前面,但排序却变化了。

1.png


1355372439_5252.jpg


如上图所示,当加入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号人物的后面。


添加英雄的函数还是不够完美,改进功能,不让有相同排名的英雄加入链表。


1.png

添加重复的英雄进去:

1.png

看结果:

1.png


没有好办法,光看是学不会的,自己动手敲代码,自己画图分析,加深理解。


本节学习代码》》》