算法初识

好多大的公司都问算法,那么在这里总结一下。

其实我个人觉得在实际项目开发中并没有用到很多的算法, 可能是我们的项目原因吧,就连平时见的最多的冒泡排序也没有用上,但是面试的时候会问到,排序、查找、删除、插入等等,还有就是各大算法的思想和算法的实现,那好吧,不积跬步,无以至千里,总是感觉算法很深奥,那咱们一起掀开算法的神秘面纱吧。

说到算法,不得不提到的就是时间复杂度空间复杂度。这两个度是什么呢,简单的说就是这么多算法,总有个高低之分吧,看看谁更牛逼!自古就有“文无第一,武无第二”一说,所以各种算法到了一起总要“攀比”一下谁更牛逼,官方语言这样描述的“算法的质量优劣将影响到算法乃至程序的效率”。那么就有了衡量的标准,就是这两个度。

(1)时间复杂度:一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

分析:随着模块n的增大,算法执行的时间的增长率和 f(n) 的增长率成正比,所以 f(n) 越小,算法的时间复杂度越低,算法的效率越高

2. 在计算时间复杂度的时候,先找出算法的基本操作,然后根据相应的各语句确定它的执行次数,再找出 T(n) 的同数量级(它的同数量级有以下:1,log2n,n,n log2n ,n的平方,n的三次方,2的n次方,n!),找出后,f(n) = 该数量级,若 T(n)/f(n) 求极限可得到一常数c,则时间复杂度T(n) = O(f(n))

根据“同中求异,异中求同”,我们设定x轴上边去一个x=10,可以得出如下结论:

(2)空间复杂度:类似于时间复杂度的讨论,一个算法的空间复杂度(SpaceComplexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。空间复杂度(SpaceComplexity)是对一个算法在运行过程中临时占用存储空间大小的量度。一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。

关于两个复杂度,借用一个网友的说法就是“愚公的精神固然可敬,但是推土机和炸药可能是更加实在和聪明”。

好了,我们大概明白了什么是时间复杂度和空间复杂度了,(说实在的,光看概念我真的不怎么明白)那么我们经常用的算法里面到底谁更厉害呢?!下图是咱们经常用的排序的一个比较(谁能告诉我timsort是啥?桶排序是啥?基数排序是啥?为啥没有二分法?还有二叉树呢?)

上图的红黄绿棕色代表的意思就是,绿色效率更高,黄色一般,红色最差。

先来一发二分法的。

二分法查找

二分法查找的思想:首先保证这个数组是一个有序的数组。首先取到第一个数和最后一个数的下标:min、max,然后取到中间数的下标mid=(min+max)/2,那么我们就能拿到中间数的数值,和我们要查找的数searchNum进行比较,两种结果:

(1)中间的数值大,那么searchNum就是中间数之,那么我们将之前的max=mid-1,(到这里就做到了二分:将数组的半部分直接舍弃,不做比较,这也是数组必须是有序数组的原因。)再进行上述操作进行比较,直到作出判断。

(2)中间的数值小,那么searchNum就是中间数之,那么我们将之前的min=mid+1,(到这里就做到了二分:将数组的半部分直接舍弃,不做比较,这也是数组必须是有序数组的原因。)再进行上述操作进行比较,直到作出判断。

二分法排序

二分法排序思想:主要思想在于while:start和middle之间的“勾当”将数组的前半部分排好序的直接忽略掉,不进行比较。

我们给一个数组@[@12,@3,@23,@34,@35,@99,@98,@43];

(1)当index=0的时候,start=0,end=-1,middle=0,temp=12,根据比较会进入while,此时middle=0,if比较的时候不成立,跳出while。j=-1=end,那么for循环不进入。repleace里面index=0和temp交换,其实就是12自己和自己交换。

(2)当index=1的时候,start=0,end=0,middle=0,temp=3,根据比较会进入while,此时middle=0,if比较成立,进入end=-1。j=0>end,则result[1]=result[0],此时数组第二数变成了12,再for循环,j=-1,不成立,跳出for循环。repleace里面index=0和temp交换,那么数组第一个数变成了3,完成了交换。

......

(3)当index=7的时候,数组变成了@[@3,@12,@23,@34,@35,@98,@99,@43];start=0,end=6,middle=0,temp=43,根据比较会进入while,此时middle=3,if比较得:34<43,进入else,start=4,再次进入while,middle=5,(二分法在此体现:start和middle之间将数组的前半部分排好序的直接忽略掉,不进行比较)。if 比较得:98>43,则end=4,再次比较start>end,所以跳出while进入for循环。j=6,result[7]=result[6],此时数组最后一个数是99。然后for循环进行:j--得到j=5,j>end,result[6]=result[5],此时数组倒数第二个数数是98,然后for循环进行:j--得到j=4,j=end,此时跳出ror循环。repleace里面index=5和temp交换,即43变成了在index为5的位置,也就是倒数第三个数。

此时数组排序完成。

注意:对于NSMutableArray的replaceObjectAtIndex:方法,用B替换了A,担心A的去向?不用担心,调用该方法的时候会对A自动调用release,所以我们不必担心A的去向。

再来一发冒泡:

冒泡排序

冒泡排序的思想就是(排序完成后是由大到小的顺序):1.比较相邻的元素。如果前面的比后边的小,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最小的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

简单的说就是:比较相邻元素,进行交换

简单排序

简单排序的核心思想:找准时机、再做替换

和冒泡相比,冒泡每次都做替换,简单排序是遍历数组后找到最小元素的下标后再做替换。

简单排序的时间复杂度也是O(N^2)。虽然简单排序和冒泡排序的时间复杂度一样,但是简单排序在性能方面还是好很多的,交换次数没像冒泡那么频繁。

希尔排序

希尔排序是一个基于插入排序的改进型插入排序算法。由于插入排序一次只能交换相邻的元素,因此元素只能一点点的从数组的一端移动到另一端。如果最小的元素在数组的末尾的话,那就需要N-1次移动,因此对于插入排序的效率是非常低的。

注意:实际就是a[0]和a[h]比较,a[1]和a[h+1]比较。。。每比较完一轮后,就缩小h的值。

理解:步长是决定希尔排序时间复杂度的关键,但是究竟应该选择什么样的步长才是最好的,目前还是一个数学难题。不过大量的研究数据表明,步长与时间复杂度存在以下关系:(看不懂下边说的是啥意思啊)

Shell排序通过将数据分成不同的组,先对每一组进行排序,然后再对所有的元素进行一次插入排序,以减少数据交换和移动的次数。平均效率是O(nlogn)。其中分组的合理性会对算法产生重要的影响。

按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的

Shell排序比冒泡排序快5倍,比插入排序大致快2倍。Shell排序比起QuickSort,MergeSort,HeapSort慢很多。但是它相对比较简单,它适合于数据量在5000以下并且速度并不是特别重要的场合。它对于数据量较小的数列重复排序是非常好的。


最后,哪里不对的地方可以给我留言,我会及时改进的,谢谢大家。

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

推荐阅读更多精彩内容

  • 概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的...
    Luc_阅读 2,253评论 0 35
  • 该系列文章主要是记录下自己暑假这段时间的学习笔记,暑期也在实习,抽空学了很多,每个方面的知识我都会另起一篇博客去记...
    Yanci516阅读 12,171评论 6 19
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,159评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,726评论 0 15
  • 回到医院,第一天上班! 冒雨出去吃饭 样子还不错!就是味道太差! 明天在院内吃食堂吧!
    失宠鬼娃阅读 81评论 0 0