跟着Sedgewick学算法(week 1 ElementarySort)
2024-09-04 15:23:59
链接https://www.evernote.com/shard/s408/sh/dbe0167f-20e0-41c4-a49b-75717ad98695/461148482ffb6add092bebc9d90a4a2a
搜索和排序一项是算法的两大主题,重要性不言而喻。Robert在第一周的lecture 2就是从基本的排序算法说起。包括选择排序(应该也叫冒泡排序)、插入排序,希尔排序(Shell Sort),附带讲了shuffle(随机序列),以及凸集。我们一点点说。
零、Total Order
零、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).
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
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,怎么判断是否是逆时针顺序的
最新文章
- A 最熟悉的陌生人 (纪念当年就读的梅州市江南高级中学)
- Nagios NSclient Failed to get CPU value: \238(_total)\6: Failed to get mutex :(
- bodybuilding
- Power string(poj 2406)
- 数据库编程与C#编程互译
- Ubuntu知识记录
- php上线教程----阿里云下设值二级域名并将项目上线
- getopt_long函数使用【转】
- Linux(CentOS7)yum安装卸载命令,离线下载安装包
- MySQL中间件之ProxySQL(13):ProxySQL集群
- JDBC 连接mysql数据库
- Maven 包含资源文件
- 说说为什么会有ssl.CertificateError报错
- 2-Fifteenth Scrum Meeting-20151215
- 2018年湘潭大学程序设计竞赛 F - maze
- ASP.NET Hashtable输出JSON格式数据
- 【X-Forwarded-For】WEB修改访客IP
- Android 五种存储方式个人总结
- SQL 之相关语法及操作符
- GeekOS课程设计-project1