链接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. 软件工程概论课堂测试一————添加新课程(web)

    设计思想 三个文件Class_add.java  add.jsp  addInput.jsp Class_add.java : 内封装方法:连接数据库.向数据库添加课程信息.判断非合理的输入情况.判断 ...

  2. [poj] 1236 networks of schools

    原题 这是一道强连通分量板子题. 显然subtask1 是要输出入度为0的点的个数 而subtask2,我们考虑一下最优一定是把一个出度为零的点连到入度为零的点上,这样我们要输出的就是max(出度为零 ...

  3. uoj228:基础数据结构练习题

    题意:http://uoj.ac/problem/228 sol  :线段树开根操作 对于节点x,可以在max[x]-min[x]<=1时直接做,转化为区间减或区间覆盖 #include< ...

  4. SQL触发器(AFTER和INSTEAD OF)

    转自:http://www.cnblogs.com/shepherldeng/archive/2010/06/23/1763766.html 何为触发器:触发器是数据库服务器中发生事件时自动执行的特种 ...

  5. 7月9日day1总结

    今天的学习过程和小结 上午学习了前端包括html,CSS,js等基本内容 前端10.25.134.187 html js css 1.块元素 ---默认占满整行,如果设置了高度和宽度都有效,如果不设置 ...

  6. 使用 redux 监听插件的使用

    首先需要在chrome浏览器当中下载redux插件 接着在你的项目当中加上**window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX ...

  7. canvas2D 基础知识 浅析

    1.canvas HTML5给出的一个可以展示绘图内容的标签 使用领域: (推荐网站:threejs.org) 1. 游戏   2. 可视化数据  3. Banner广告  4. 多媒体 (1)在 c ...

  8. 母函数(Generation Function) 入门 + 模板

    转自:母函数 入门 + 模板  感谢 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用母函数解决问题的 ...

  9. bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级——分层图+dijkstra

    Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i ...

  10. 快来看看Google出品的Protocol Buffer,别只会用Json和XML了

    前言 习惯用 Json.XML 数据存储格式的你们,相信大多都没听过Protocol Buffer Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存 ...