鱼C论坛

 找回密码
 立即注册
查看: 3310|回复: 2

[学习笔记] 插入排序与算法的数学分析

[复制链接]
发表于 2017-6-9 20:13:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 超凡天赐 于 2017-6-9 20:18 编辑

小甲鱼老师已经说了关于插入排序,我们非常困惑关于时间是怎么分析出来的?这里再对插入排序

进行更深一步的数学分析。(这里并没有用到多么高深的数学知识,只不过是标题党罢了)

话不多说,先举个关于扑克牌的例子。

假如我们这里有十张牌。

cards.png

我们来想象这个场景,我们先将十张牌放在桌子上,左手抽出第一张。下面我将用十分形象的方法来描述抽象的算法。注意看注释。

  1. //这里我们将分成两堆,一堆在左手上,另一堆在桌子上。我们不难发现其实左手上完全排序好的,桌子上是没有排序好的。
  2. #include <stdio.h>
  3. int main()
  4. {
  5.     int i,j,right_hand;
  6.     int card[10]={1,2,3,4,5,6,7,8,9,10};
  7.     for(i=1;i<=9;i++)
  8.     {
  9.         right_hand=card[i];//这里我们将需要插入的牌从桌上放到右手上,此时我们左手已经有一张牌了(只有一张牌,当然排序好了)。
  10.         j=i-1;//我们再把目标放到左手上。
  11.         while(j>=0&&card[j]<right_hand)
  12.         {
  13.             card[j+1]=card[j];
  14.             j--;
  15.         }//在这里我们来想象一个动作,其实和我们平时理牌一个道理。我们拿右手上的牌和左手上最后一个牌先进行比较。如果右手上的牌大于左手上的牌,那么就将左手上最后一张牌向后移,倒数第二张还是这样,就还后移,直到找到合适的插入点。
  16.         card[j+1]=right_hand;//这里为什么是j+1。其实这并不是逻辑上的问题,这是计算机指令的问题。因为这里最后j多减了一次1.
  17.     }
  18.     for(i=0;i<10;i++)
  19.         printf("%d ",card[i]);
  20.     return 0;
  21. }
复制代码


仿佛算法就在眼前,摸得着,看得见。

分析算法:(见代码注释)

  1. //这里只对主要程序段进行时间分析
  2. //假设c是执行时间,n是执行次数
  3. #include <stdio.h>
  4. int main()
  5. {
  6.     int i,j,right_hand;
  7.     int card[10]={1,2,3,4,5,6,7,8,9,10};
  8.     i=0;//c0
  9.     while(i<=9)//c1  n=11
  10.     {
  11.         right_hand=card[i];//c2  n-1
  12.         j=i-1;//c3  n-1
  13.         while(j>=0&&card[j]<right_hand)//c4  1+2+···+n-1
  14.         {
  15.             card[j+1]=card[j];//c5  1+2+···+n-2
  16.             j--;//c6  1+2+···+n-2
  17.         }
  18.         card[j+1]=right_hand;//c7  n-1
  19.         i++;//c8  n-1
  20.     }
  21.     for(i=0;i<10;i++)
  22.         printf("%d ",card[i]);
  23.     return 0;
  24. }
复制代码


好了,现在我们要进行求和,也就是求总时间。

我们先假设最坏情况,我写的那个C语言代码就是最坏情况。

数学公式.png

在这里,我们认为当n趋近于无穷大时,我们就可以认为这个算法的效率为n(o^2)

为什么?这里我来引入数学中的等价无穷大(其实这个是我瞎扯的,我没有找到什么依据)

daum_equation_1497008988065.png

在分析算法效率时,我们总是把低阶的无穷大给扔掉,所谓低阶,是相对的,所以算法效率最差为n(o^2)

当最好的情况时呢?

回到上面的代码我们假设是排列好的,c4的执行次数就变成了n-1,所以这个算法效率最优为n(o);

那么平均呢?

这里就不用什么概率论了,就假设平均为一半比它大,一半比它小,c4的执行次数就变成了(1+2+···+n-1)/2,

我们再次按照上面的最差效率进行推导,

我们发现仍是o(o^2)!!!平均效率竟然和最差效率一样!!!!

这里其实还不是严格的数学证明,数学证明必须所有情况都成立才可以。

评分

参与人数 3荣誉 +11 鱼币 +16 贡献 +11 收起 理由
小甲鱼 + 5 支持楼主!
零度非安全 + 6 + 6 + 6 非常的nice
人造人 + 5 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-9 20:16:14 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-9 22:17:45 | 显示全部楼层
能帮我移到数据结构与算法吗?我放错地方了@人造人
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 02:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表