chapter1.找出你最不常用的几件衣物

在chapter0 中,我们设计了一个产品,叫私人衣橱。这个手机app帮助我们管理衣物,方便我们查找衣物的位置,也可以展示我们的衣服。
现在这个app要添加新功能:

  • 找出过去一年中,自己最不常用的10件物品,看是否需要转卖或者扔掉。

怎么实现这个功能呢?方法有很多,我们先来介绍第一种方法:

“堆”

这个堆不是土堆、人堆,而是数据的堆。

特征

计算机语言里的描述:堆是指一个特定的基于树结构的数据结构。
我们先不管这个抽象的描述,我们只需要记住堆的特征:
一.任何一个节点不大于父亲节点(大根堆)
比如下面这幅图,2的父节点是17,17的父节点是19,是不是子节点小于父节点。不过19不是2的父节点,因为中间跨了一层。其他以此类推。100叫根节点,因为它已经到顶了,没有父节点。


堆-数据结构

二.它必须是一棵完全二叉树:就是除了最后一层节点外,其他层节点数必须是两个,最后一层的所有节点集中在最左侧。
如下图:


p1

它是一个正确的例子:55必须有两个子节点:22;25。22和25 不一定是有两个子节点,因为他们已经最后一层。

又如下图:


p2

它是一个错误的例子,为什么?最后一层的所有节点没有集中在最左侧。因为子节点必须从上往下,从左往右添加。

了解完堆的概念,那么堆有哪些分类呢?
首先是:大根堆,即根节点的值最大,逐层递减,最下面一层的数据最小。
再次是小根堆:正好和大根堆相反。

介绍完堆,我们回到上面的问题,假设我们有一系列的衣物,他们的使用频率分别是:35 33 42 10 14 19 27 44 26 31,我们将组数据构建成一个大根堆,从下往上层级的节点必然是小的值。

最终的结果是这样的:


大根堆

具体构建大根堆的步骤:
Step 1 − 在堆的底部创建一个新节点
Step 2 − 将值放在该节点
Step 3 − 比较新关键的节点值与它的父节点值大小
Step 4 − 如何父节点值小于新节点值,那么交换他们
Step 5 − 重复第三步和第四部

堆的创建

好了,现在堆创建好,我们需要将频率最低的几个数据取出,堆是一种特殊的树(一种数据结构,后面再介绍),遍历数据有两种方式:广度遍历和深度遍历,方式如名字:
广度遍历方向:


广度遍历

遍历出来的数据是:
44 42 35 33 31 19 27 10 26 14

深度遍历方向:


深度遍历

遍历出来的数据是:
44 42 33 10 26 31 14 35 19 27

利用广度遍历,已经基本是从大到小了,后面的几个就已经基本满足我们的要求了。而且我们还可以知道,根节点就是我们使用频率最高的衣物。
但是我们也发现,广度遍历出来的数据,并不绝对是最后一个数据就是频率最低,这个怎么解决呢?
解决办法是:

排序

将使用频率:35 33 42 10 14 19 27 44 26 31,这组数据进行从高到底排序。也就实现我们的功能。

那排序的算法怎么设计呢?

选择排序(常规思维想到的第一个方法)

思想:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

算法描述
n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:

  • 初始状态:无序区为R[1..n],有序区为空;
  • 第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
  • n-1趟结束,数组有序化了。
选择排序.gif
冒泡排序

冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

算法描述

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
  • 针对所有的元素重复以上的步骤,除了最后一个;
  • 重复步骤1~3,直到排序完成。
冒泡排序.gif
归并排序(Merge Sort)

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

算法描述

  • 把长度为n的输入序列分成两个长度为n/2的子序列;
  • 对这两个子序列分别采用归并排序;
  • 将两个排序好的子序列合并成一个最终的排序序列。


    归并排序.gif
基数排序(Radix Sort)

基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。

算法描述

  • 取得数组中的最大数,并取得位数;
  • arr为原始数组,从最低位开始取每个位组成radix数组;
  • 对radix进行计数排序(利用计数排序适用于小范围数的特点);


    基数排序.gif

排序的算法还有很多,就不一一介绍了。

总结

选择排序:不停找最小值(效率也是最低的)
冒泡排序:相邻比较,不停交换,冒泡
归并排序:分组,不同组之间比较
基数排序:非比较类算法,先低优先级再高优先级排序
上面的堆也是也可以达到排序的目的。

通过排序,我们就可以得到降序的一个数组:
10 14 19 26 27 31 33 35 42 44

还怕找不到你最不常用的衣物吗?好了,最不常用的衣物已经找到了,快去处理掉把。

其他知识

堆的删除

从叶子开始添加,删除的时候从根节点开始删除。

具体的步骤是:
Step 1 − 删除根节点.
Step 2 − 移动最近一层的最近一个元素到根节点位置
Step 3 − 比较它与子节点值的大小
Step 4 − 加入父节点值小于子节点值,则相互交换
Step 5 − 重复第三步和第四步


堆的删除

排序图来自https://www.cnblogs.com/onepixel/articles/7674659.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • 1)这本书为什么值得看: Python语言描述,如果学的Python用这本书学数据结构更合适 2016年出版,内容...
    孙怀阔阅读 12,391评论 0 15
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,067评论 1 32
  • 堆就是用数组实现的二叉树,所以它没有使用父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。...
    唐先僧阅读 248,590评论 21 252
  • 愿你已放下,常驻光明中
    椿去湫来海棠已开阅读 124评论 0 0
  • 第二天,下午4点我问蛋“起床了没?”蛋“没有,考虑要不要继续睡”“好好考虑,千万不要睡到一半饿醒了”“好吧!我去找...
    空灵愿阅读 184评论 0 1