首先要知道一个算法的好坏主要是从算法的时间复杂度、空间复杂度和稳定性来衡量。
实际上把求解问题的关键操作,如加减和比较运算指定为基本操作,然后把算法执行基本操作的次数作为算法的时间复杂度,而算法执行期间占用的存储单元的数量成为算法的空间复杂度。
一个算法的时间耗费就是该算法钟所有语句的频率值和(记做T(n))。当问题规模n无穷大时,T(n)的数量级成为时间复杂度,记做T(n)=O(f(n))
常见的 时间复杂度有O(1)叫常数阶,O(n)叫做线性阶,O(n^2)叫做平方阶
1、常数阶
执行的次数都是恒定的,不会随着n的变化而变化,所以单纯的分支接受,其时间复杂度也是O(1)。
2、线性阶
线性阶最具典型的例子就是迭代。例如遍历数组的中的每一个元素。整个遍历过程总时间和数组的长度呈正比(线性增长)。
3、对数阶
var count =1
while count < n {
count = count *2
}
上述代码中不难法相,当count大于等于n的时候,整个循环就结束了。可以看出再次之前,循环执行次数符合:2^x=n这个公式,x=log2n。所以上述代码的时间复杂度为O(logn)。
4、平方阶
平方阶就不做过多解释,简单想象for循环嵌套for循环便理解了。
冒泡排序 - 简书
选择排序 - 简书
插入排序 - 简书
快速排序 - 简书
归并排序 - 简书
二分查找 - 简书
希尔排序 - 简书
五 堆排序
堆 是具有下列性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆;或者每个节点的值都小于或等于其左右孩子结点的值称为小顶堆。
来源:图解排序算法(三)之堆排序 - dreamcatcher-cx - 博客园
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
图解:图解排序算法(三)之堆排序 - dreamcatcher-cx - 博客园
六 哈夫曼树
又称最优二叉树,是指一组带有确定确定权值的叶子节点所构造的确有带全路径长度最短的二叉树,聪树中的一个结点到另一个结点之间的分支构成了两结点之间的路径,路径中的分支个数成为路径长度,二叉树的路径长度是指由根节点到所有叶子节点的路径长度之和。
七 Hash算法
Hash表采用一个映射函数 f :key —> address 将关键字映射到该记录在表中的存储位置,从而在想要查找该记录时,可以直接根据关键字和映射关系计算出该记录在表中的存储位置,通常情况下,这种映射关系称作为Hash函数,而通过Hash函数和关键字计算出来的存储位置(注意这里的存储位置只是表中的存储位置,并不是实际的物理地址)称作为Hash地址。比如上述例子中,假如联系人信息采用Hash表存储,则当想要找到 “lisi” 的信息时,直接根据 “lisi” 和 Hash 函数计算出 Hash 地址即可。
Hash 表的优缺点及注意点
优点
哈希表的效率非常高,查找、插入、删除操作只需要接近常量的时间即0(1)的时间级。如果需要在一秒种内查找上千条记录通常使用哈希表,哈希表的速度明显比树快,树的操作通常需要O(N)的时间级。哈希表不仅速度快,编程实现也相对容易。如果不需要遍历数据,不二的选择。
缺点
它是基于数组的,数组创建后难于扩展。有些情况下,哈希表被基本填满时,性能下降得非常严重,所以开发者必须要清楚表中将要存储的数据量。或者也可以定期地把数据转移到更大的哈希表中,不过这个过程耗时相对比较大。
注意点
在设计Hash算法的时候。一定要保证相同字符串产生的 Hash 值相同,同时要尽量的减小Hash冲突的发生,这样才算是好的 hash 算法。
iOS系统API给我们提供一个自动过滤重复元素的容器 NSMutableSet/NSSet,如:当我们向该实例对象中添加字符串时,如果重复添加两个相同的字符串,集合中只会保留一个