链接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. Vuex, api, SSR, module

    vuex https://vuex.vuejs.org/zh/guide/actions.html 单向数据流 单例模式 & 多个组件共享状态 State & 状态注入 Vue.use ...

  2. [luogu4242] 树上的毒瘤

    题目描述 这棵树上有n个节点,由n−1条树枝相连.初始时树上都挂了一个毒瘤,颜色为ci.接下来Salamander将会进行q个操作. Salamander有时会修改树上某个点到另外一个点的简单路径上所 ...

  3. MyBatis原理分析

    MyBatis原理分析   参考博客: 深入理解mybatis原理: http://blog.csdn.net/luanlouis/article/details/40422941 一 . JDBC的 ...

  4. SyntaxError: Unexpected token ' in JSON at position 1

    刚才遇到一个问题: 在公司两个不同的环境竟然会出现错误 对比一下两个环境的数据,发现一个传来的是双引号的JSON字符串,一个是单引号.而当我用JSON.parse()时,就会报错!! 原因是JSON. ...

  5. 洛谷P1522 牛的旅行

    题目描述 农民 John的农场里有很多牧区.有的路径连接一些特定的牧区.一片所有连通的牧区称为一个牧场.但是就目前而言,你能看到至少有两个牧区通过任何路径都不连通.这样,Farmer John就有多个 ...

  6. 汕头市队赛 SRM 09 B 撕书

    B 撕书II-3 SRM 09 背景&&描述 琉璃手头有一黑一白两本魔法书,一本是<缟玛瑙的不在证明>,另一本是<白色相簿1.5>     传说同时打开这两本书 ...

  7. 转 Linux内存管理原理

    Linux内存管理原理 在用户态,内核态逻辑地址专指下文说的线性偏移前的地址Linux内核虚拟3.伙伴算法和slab分配器 16个页面RAM因为最大连续内存大小为16个页面 页面最多16个页面,所以1 ...

  8. (九)经典_STM32_ADC多通道采样的例子

    STM32 ADC多通道转换描述:用ADC连续采集11路模拟信号,并由DMA传输到内存.ADC配置为扫描并且连续转换模式,ADC的时钟配置为12MHZ.在每次转换结束后,由DMA循环将转换的数据传输到 ...

  9. (二十七)Linux的inode的理解

    一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...

  10. python2 登录带验证码的页面

    #!/usr/bin/python#-*- coding: utf-8 -*- import os,json;import urllib,urllib2;import cookielib; #获取co ...