by Richard Johnsonbaugh Marcus Schaefer
6.1 插入排序
本算法将数组a排序,方法是首先将a[2]插入已经有序的数组a[1];再将a[3]插入已经有序的数组a[1],a[2];依此类推;最后将a[n]插入已经有序的数组a[1],…,a[n-1]。
Input Parameter: a
Output Parameter: a
insertion_sort(a){
n = a.last
for i=2 to n{
val=a[i]//保存a[i],以备插入正确位置
j = i-1
//若 val<a[j],则a[j]右移,为a[i]腾出位置
while(j>=1 && val<a[j]){
a[j+1]=a[j]
j = j-1
}
a[j+1]=val//插入val
}
}
算法最坏情况为O(n²)。
6.2 快速排序
将要排序的数组分成两部分,然后对每个部分进行排序。这种分割过程称为分区(partition)。分区取决于所选择的一个特别元素为分区元素。
分区算法:本算法将数组a[i],...,a[j]进行分区,方法是在下标h出插入val=a[i],这个位置正是数组排序后它应处的位置。算法结束时,下标比h小的单元值小于val,儿下标比h大的单元的值大于或等于val。算法回送下标h。
Input Parameters: a,i,j
Output Parameter: a
quicksort(a,i,j){
val=a[i]
h=i
for k=i+1 to j
if(a[k]<val){
h = h+1
swap(a[h],a[k])
}
swap(a[i],a[h])
return h
}
快速排序(Quicksort)。本算法利用分区算法对数组a[i],...a[j]进行排序。
Input Parameters: a,i,j
Output Parameter: a
quicksort(a,i,j){
if(i<j){
p = partition(a,i,j)
quicksort(a,i,p-1)
quicksort(a,p+1,j)
}
}
快排的最坏情况为O(n²)。
随机化的快速排序是选择分区元素时不总选择第一个,而是随机选择。
6.3 排序问题的下届
为了对n个项进行排序,任何基于比较的排序算法都有最坏情况Ω(nlgn)。
基于比较:是指算法到底将一个元素放在数组中的什么位置,只有通过将数组中一个元素与另一个元素进行比较才能确定。
堆阵排序、插入排序、归并排序和快速排序都是基于比较的排序算法。
6.4 计数排序和基数排序
计数排序对每个值的个数进行计数,每个正数范围在0到m,包括0和m。然后利用得到的这组数据对原始的数据进行排序。
如a[1]=5,a[2]=8,a[3]=3,a[4]=8,a[5]=10,a[6]=7
如果c[k]是数组a中小于或等于k的元素的个数:
c[3]=1,c[5]=2,c[7]=3,c[8]=5,c[10]=6
然后把a中的项复制到另一个数组b,这个数组硬是被排序的。复制从a的最后一个元素开始。
a中最后一个元素是7。由于c[7]=3,所以a中有3个元素小于等于7。因此一旦a被排序,7应当放在第三单元。依此类推。
计数排序算法:本算法将整数数组a[1],...a[n]排序,每个正数的范围在0到m。
Input Parameters: a,m
Output Parameter: a
counting_sort(a,m){
//设置c[k]=数组a中值k出现的次数。
//开始讲c初始化为0。
for k=0 to m
c[k]=0
n = a.last
for i=1 to n
c[a[i]]=c[a[i]+1]
//修改c,使c[k]=小于等于k的元素个数
for k=1 to m
c[k]=c[k]+c[k-1]
//用b中的结果对a排序
for i= n downto 1{
b[c[a[i]]]=a[i]
c[a[i]] = c[a[i]]-1
}
//将b复制回a
for i = 1 to n
a[i] = b[i]
}
基数排序针对整数很大的情况。首先用一个稳定排序算法(例如计数排序)按最低位有效位(个位)对这些整数排序,然后按次低位排序,等等,知道最后按最高位进行排序。
基数排序:本算法对整数数组a[i],...,a[n]进行排序。每个整数最多有k位。
Input Parameters: a,k
Output Parameter: a
radix_sort(a,k){
for i=0 to k-1
counting_sort(a,10的i次方)//键值是10的i次方位处的数字
}
6.5 选择
选择问题:给定一个数组a和一个整数k,寻找第k个最小元素。
一般采用分区算法版本。分区元素最终放在第i个位置,若k=i成功;若k<i则仅对于小于i的部分再分区递归执行;若k>i,对大于i的部分再分区递归执行。
随机选择。令val是数组a[i],...,a[j]已排序后位于下标k的单元中的值都小于val,所有下标大于k的单元中的值都大于或等于val。算法中使用了随机分区算法。
Input Parameters: a,i,j,k
Output Paramerer: a
random_select(a,i,j,k){
if(i<j){
p=random_partition(a,i,j)
if(k==p)
return
if(k<p)
random_select(a,i,p-1,k)
else
random_select(a,p+1,j,k)
}
}