链接https://www.evernote.com/shard/s408/sh/dbe0167f-20e0-41c4-a49b-75717ad98695/461148482ffb6add092bebc9d90a4a2a
 
 搜索和排序一项是算法的两大主题,重要性不言而喻。Robert在第一周的lecture 2就是从基本的排序算法说起。包括选择排序(应该也叫冒泡排序)、插入排序,希尔排序(Shell Sort),附带讲了shuffle(随机序列),以及凸集。我们一点点说。


零、Total Order

A total orderis a binary relation ≤that satisfies:
1。Antisymmetry: if v ≤ w and w ≤ v, then v= w.
2。Transitivity: if v ≤ w and w ≤ x, then v ≤ x.

3。Totality: either v ≤ w or w ≤ vor both.


一、选择排序
 
如下原始序列:
   a= [ 9 2 1 4 8 7 5 6 3]
           i=0
经过一次swap
  a= [ 1 2 9 4 8 7 5 6 3]
            i=1
经过两次swap(索引1和索引1交换)
  a= [ 1 2 9 4 8 7 5 6 3]
               i=2
从序列中选出最小的 也就是1,索引为2,a[i]与a[2]交换,i=i+1,从余下的序列中再选出最小的,也即2,a[1]与a[1]交换,也即保持不动,循环知道最后一个元素,c#简单代码:
        public void SelectSort(ref int [] a)
        {
            int count = a.Length;
            for ( int i = 0; i < count; i++)
            {
                int min = i;
                for ( int j = i+1; j <count; j++)
                {
                    if (a[j] < a[min]) min = j;
                }
                Swap( ref a, i, min);
            }
        }
        public void Swap( ref int[] a , int i, int j)
        {
            int temp = a[i] ;
            a[i] = a[j];
            a[j] = temp;
        }
选择最小值需要比较的次数 N-1+N-2+……+2+1+0 ~N^2/2,元素交换的次数N。
即使输入时已经排序好的,也要经过Quadratic time。数据移动是线性的,而且不需要额外空间。

二、插入排序
如下原始序列:
   a= [ 9 2 1 4 8 7 5 6 3]
           i=0
经过一次插入
  a= [ 2 9 1 4 8 7 5 6 3]
            i=1
经过两次插入
  a= [ 1 2 9 4 8 7 5 6 3]
               i=2
不描述过程,太难了,直接看代码吧
       public void Swap( ref int[] a ,int i,int j)
        {
            int temp = a[i] ;
            a[i] = a[j];
            a[j] = temp;
        }
        public void InsertSort( ref int[] a)
        {
            int count = a.Length;
            for ( int i = 0; i < count; i++)
            {
                for ( int j = i; j > 0; j--)
                {
                   if(a[j]<a[j-1]) Swap( ref a, j,j-1);
                    else break;
                }
            }
        }
用插入排序,对于个随机的数列,需要1/4*N^2比较和1/4*N^2次交换,不需要额外空间。
如果输入序列式最好的,即已经升序排好的,只需N-1次比较和0次交换
最坏情况,如果输入是降序排好的,将需要1/2*N^2次比较和1/2*N^2交换

三、shell排序
感觉shell排序和插入排序差不多,算是插入排序的一种,和插入排序不同,shell排序每次不是和后继元素比较,而是和一定步长之后的元素比较,每个元素都如此,一轮过后,缩小步长,继续知道步长为1,此时也就是插入排序,得出结果。
根据数据大小来选择步长,步长一般有:
1.  1,2,4,8,16......也就2的幂
2.  1,3,7,15....2的幂减1
3. 3x+1,即1,4,13,40,121....
还有就是
4. Sedgewick. 1, 5, 19, 41, 109, 209, 505, 929, 2161, 3905, …
 
据robert介绍,1不行,2一般,3还好,4最好(也就是他自己提出的)。没有证明~~~
方便写代码,用3的步长~~
         public void ShellSort( ref int[] a)
        {
            int count = a.Length;
            int h =1;
            while (h < count / 3) h = h * 3 + 1; //先找到最大的步长
            while (h>=1)
            {
                for ( int i = 0; i+h<count; i++)//ps纸上得来终觉浅,这一步没写好,因为a[i]和a[i+h]比较后,如果a[i+h]小于a[i],那么a[i+h]要继续和
                {                               //a[i]之前的元素比较,以前我以为不需要呢,所以搞错了。需知此事要躬行啊啊啊
                    for ( int j = i + h; j >=h && a[j] < a[j - h]; j--)
                    {
                        Swap( ref a, j, j - h);
                    }
                }
                h = h / 3;
            }
        }
    
Proposition. The worst-case number of compares used by shellsort with
the 3x+1 increments is O(N3/2).
 
希尔排序目前还没有accurate model!!!
为什么对希尔排序感兴趣?
 
1.现实中,对于较小的序列,排序很快,可以用在嵌入式系统
2.虽然是简单的算法,但性能很不错。而且还有很多问题未解决,如算法的渐进增长率、最佳步长序列,平均性能。
3.所以说,还有好的算法等待发现。
 

四、随机序列
比较简便的方法是:
1 2 3 4 5 6 7 8 9
对于该序列,每一个数字都随机生成一个随机数,然后按随机数大小排序。
 
Proposition. Shuffle sort produces a uniformly random permutation
of the input array, provided no duplicate values,where assuming real numbers uniformly at random
 
Knuth提出的一个方法是:在第i次迭代时,随机选择0到i之间的整数r,然后交换a[i]和a[r].
Proposition:Knuth的shuffle算法能在线性时间能得到一个均匀随机数列。
便于分析,从i=1开始,考虑第一个元素,也就考虑索引为1位置的元素
在开始第1次时
i=1;r=1; 索引1的元素保持不变
在第2次时
i=1,2,索引1 和 2交换位置的概率为1/2,索引1的元素在1或者2位置上的概率是1/2
在第3次时
i=1,2,3,原始1位置上的元素换到第三个位置上的概率1/2*1/3+1/2*3=1/3
同理,第4次
i=1,2,3,4 原始1位置的元素,在每个位置上的概率 1/3*1/4+1/3*1/4+1/3*1/4=1/4
依次推下去可医治,每个元素在任意位置的概率为1/N。
简单代码如下
public static void shuffle(ref int[] a)
{
int N = a.length;
for (int i = 0; i < N; i++)
{
int r = Random(i + 1);
swap(ref a, i, r);
}
}
一个实例,online poker 在线扑克的程序bug。
做到真正的shuffle其实挺难的。也可以依赖硬件,随机数产生器blabla不叙说了。

五 凸集
 
实数 R (或复数 C 上)在向量空间中,如果 S 中任两点的连线内的点都在集合 S 内,集合 S 称为凸集。
一个直白叙述就是,从一个点开始,可以一直逆时针找到一个点,点与点连线,能将所以点都包住。
下面就是凸集。
 
 
懒得写了,给出三个点序,a->b->c,怎么判断是否是逆时针顺序的
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

跟着Sedgewick学算法(week 1 ElementarySort)的更多相关文章

  1. 跟着Sedgewick学算法(week 1 UnionFind)

    发现笔记转过来,没有图的~~~~~~~~~~~悲剧,给出共享笔记链接 https://www.evernote.com/pub/yanbinliu/algorithm 很久之前就在coursera看到 ...

  2. 1164: 零起点学算法71——C语言合法标识符(存在问题)

    1164: 零起点学算法71——C语言合法标识符 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 10 ...

  3. 1163: 零起点学算法70——Yes,I can!

    1163: 零起点学算法70--Yes,I can! Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: ...

  4. 1147: 零起点学算法54——Fibonacc

    1147: 零起点学算法54--Fibonacc Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 20 ...

  5. 1145: 零起点学算法52——数组中删数II

    1145: 零起点学算法52--数组中删数II Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 293 ...

  6. 1137: 零起点学算法44——多组测试数据输出II

    1137: 零起点学算法44--多组测试数据输出II Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: ...

  7. 1136: 零起点学算法43——多组测试数据输出I

    1136: 零起点学算法43--多组测试数据输出I Time Limit: 1 Sec  Memory Limit: 128 MB   64bit IO Format: %lldSubmitted: ...

  8. 1135: 零起点学算法42——多组测试数据(求和)IV

    1135: 零起点学算法42--多组测试数据(求和)IV Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted ...

  9. 1134: 零起点学算法41——多组测试数据(a+b)III

    1134: 零起点学算法41--多组测试数据(a+b)III Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitt ...

随机推荐

  1. 团队冲刺Alpha(六)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...

  2. 为啥shmem不回收 | drop_caches

    内核在哪里禁止对tmpfs中内存页的回收 mem.limit_in_bytes同样会触发shrink_zones过程! shrink_zones是代码中的直接内存回收路径 1.try_to_free_ ...

  3. 基于eclipse+maven创建web工程

    Eclipse+Maven创建webapp项目<一> 1.开启eclipse,右键new——>other,如下图找到maven project 2.选择maven project,显 ...

  4. Tensorflow 载入数据的三种方式

    Tensorflow 数据读取有三种方式: Preloaded data: 预加载数据 Feeding: Python产生数据,再把数据喂给后端. Reading from file: 从文件中直接读 ...

  5. root权限

    点击左侧终端标 步骤阅读 2 出现命令提示符 3 首先输入:sudo passwd root(设置root密码) 4 输入当前系统的账户密码(账户:admin-pc的密码) 5 输入新的root密码, ...

  6. 【IDEA】使用intellij的idea集成开发工具中的git插件

    注意:这里并没有介绍git客户端的安装,如果要安装客户端,大家可以参考如下的链接: http://www.runoob.com/git/git-install-setup.html 1.在使用这个id ...

  7. UVALIVE 3972 March of the Penguins

    最大流建图比较容易第一次Dicnc抄了下别人的版 存一下以后方便查 #include <map> #include <set> #include <list> #i ...

  8. Android AutoCompleteTextView控件实现类似百度搜索提示,限制输入数字长度

    Android AutoCompleteTextView 控件实现类似被搜索提示,效果如下 1.首先贴出布局代码 activity_main.xml: <?xml version="1 ...

  9. 如何让springboot中的某些html文件不经过thymeleaf模板解析?

    这个thymeleaf有时有用,有时用不着. 但默认设置,所有的html都会经过它解析. 我的作法,是新建public,在resource里,所有css,js所放里面.(当然,static下也是OK的 ...

  10. VS2015自动添加注释

    记录下创建一个MVC5下的Models文件夹下的代码添加自动注释修改文件路径位置: 让VS自动生成类的头部注释,只需修改两个文集即可,一下两个路径下个有一个 Class.cs文件 C:\Program ...