生活中,我们总有各种大大小小的衣物,放在不同的柜子或者格子中。
衣服箱子.jpeg
适合把衣物叠起来,放里面。
衣物格子.jpg常用放小件衣物
问题:这两种容器,特点是什么?
最简单的数据结构: 栈和数组
栈
栈这种数据结构的显著特征是先进后出。所以栈,放入衣服方便,但取不方便,放置的时候我们一个个往上堆,但是取的时候必须从最上面一个开始取。图1的箱子就类似于栈的结构。
如下所示:
数组
数组:取出方便,只要知道第几个位置,但容易空间浪费。计算机世界里,为了不浪费空间,数组是不能有空档,也就是说取出的时候,必须将后续数据往前填入。图2的格子就类似于数组。
数组是线性的存储结构,且有固定的大小,比如数组的名字叫a, 那么数组的第一个位置a[0],存储这value是4。
数组
数组的查找,我们可以随机访问,比如a[6],即可以查到90的一个值。
是不是很方便,那数组的添加和删除呢?
添加数据
上图表示了添加的过程,在a[3]之后添加一个99的数据,
第一步,将数组扩容;
第二步,将a[3]之后的数据全部往后挪一个位置;
第三步,在空出来的a[4]位置上放入99这个数据。
删除数据:
删除数据
上图表示了删除的过程,比如删除a[4]的数据7,
第一步,将a[4]的数据7删除;
第二步,但是a[4]位置还在,故将a[5]之后的数据挨个往前填;
第三步,最后删除多余的空间。
所以数组的删除和添加是不是比较麻烦?主要往中间添加数据或者删除数据,都必须移动它后续的数据。除非你操作末尾的数据。
所以我们可以看到,上面两种的放置方式,其实有各自优缺点。并非特别完美。
问题:我印象中有一件什么衣服的衣服,但我不记得放哪了。有什么样的存储方式,可以解决这个问题吗?
答案是:链表
链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。
所以当往链表里面添加数据的时候,只需要修改插入点的指针,删除也类似,请看下面示意图:
添加数据
上图演示了添加黑色数据的过程。
删除数据上图演示了删除绿色数据的过程。
但是当我们在链表中检索某一条数据的时候,必须从头开始检索。
当然除了单项链表,还有较为复杂点的双向链表以及环形链表,用来提高查询速度。
将上面的颜色换成衣物,箭头换成柜子地址。就成了下图所示:
链表.png
查找帽子的位置, 只要从鞋子A,按图索骥方式,即可查到。
如果大衣换位置了,只需要将鞋子A的地址修改到大衣的新地址。
所以这上面数据都不是孤零零的存在,而是在一个链路中。这些地址也不需要连续,分散存储。
可能有人质疑了,这种方式在实际生活中不方便,每次重新换位置了,都需要修改另一个指向它的鞋子。
但要知道这个 在计算机中,是非常方便的,只是一个值而已。如果将这个设计,实现在手机软件中,其实你就感知不到修改的过程。
问题:但是我是懒人,我不想记衣服放的地方。我只想随心取衣物。 有办法吗?
将衣物柜设计类似丰巢的柜子:
柜子
衣物各自独立放入一个柜子的时候,柜子自动提取衣物特征:比如颜色,品类以及柜子号码,生成一串编号。
取的时候,在屏幕上的输入框,输入这一串编号取衣服。这个数据结构叫:
哈希表(Hash表)
哈希表的存储,有两部分组成,分别是KEY 和 VALUE:
hash表
比如我们要存储衣物,Key是根据一定规则(hash函数)生成的hash值(编号),Value存的是衣物。
当我们查找的时候,只需要根据key,就可以检索到对应的value。
这是不是就解决你懒得记衣物位置的问题了。
当然了取的时候呢?我总不能根据一串数字取衣服? 这时候,比如可以开发个软件,记录这个数字与衣服图片,我在手机上翻看衣服图片,再输入这一串数字,或者扫描二维码,打开柜子拿衣服。
链表+Hash表 叫哈希链表是比特币,区块链的基础数据结构
小小的总结
栈:特点是先进后出,放入方便,但取不方便。
数组:特点是查询方便,但是往中间添加不方便,需要挪到其他的位置。
链表:每个点包含了上一个点的地址,可以分布式,而不需要集中式存储数据。所有数据都一条链上。
哈希表:兼具了存储的灵活性和数据查询的高效性。
问题:利用上面的算法,我们可以来做什么?
私人衣橱1.0版本
解决的痛点:经常忘记我有多少衣服,也不想记放哪。
基本功能:
1.收录衣物;
2.查询位置、展示你所有的衣物;
网友评论