前提
void X_Sort ( ElementType A[], int N )
大多数情况下,为简单起见,讨论从小大的整数排序 N是正整数
只讨论基于比较的排序(> = < 有定义)
只讨论内部排序
稳定性:任意两个相等的数据,
排序前后的相对位置不发生改变
没有一种排序是任何情况下
都表现最好的
冒泡排序
void Bubble_Sort(ElementyType A[], int N)
{
for(int p = N-1; p >=0;p--)
{
int flag = 0;
for(int i = 0; i<p; i++)
{
if(A[i]>A[i+1]
{
Swap(A[i], A[i+1]);
flag = 1;
}
}
if(flag == 0) break; //全程无交换,跳出循环
}
}
最好情况: 顺序T= O(N)
最坏情况:逆序 O(N^2)
相等的不做交换,严格递增的才交换, 稳定排序
单向链表 存储 怎么排序呢
直接插入排序:
void Insertion_Sort(ElementType A[], int N)
{
for(int p=1; p< N;p++)
{
int Tmp = A[p];
for(int i = p; i> 0 && A[i-1]>Tmp; i--)
A[i] = A[i-1];
A[i] = Tmp;
}
}
不用哨兵,假设最初手里有一张牌了,然后起到新牌插到手里
如果序列基本有序,简单高效
最好情况:顺序T = O( N )
最坏情况:逆序T = O( N2 )
时间复杂度下界
对于下标i<j,如果A[i]>A[j],则称(i,j)是
一对逆序对(inversion)
问题:序列{34, 8, 64, 51, 32, 21}中有多少逆序对?
交换2个相邻元素正好消去1个逆序对!
插入排序:T(N, I) = O( N+I )
—如果序列基本有序,则插入排序简单且高效
定理:任意N个不同元素组成的序列平均具有
N ( N - 1 ) / 4 个逆序对。
定理:任何仅以交换相邻两元素来排序的算
法,其平均时间复杂度为 ( N2 ) 。
这意味着:要提高算法效率,我们必须
每次消去不止1个逆序对!
每次交换相隔较远的2个元素!
希尔排序
定义增量序列DM > DM-1 > … > D1 = 1
对每个Dk 进行“Dk-间隔”排序( k = M, M-1, … 1 )
注意:“Dk-间隔”有序的序列,在执行“Dk-1-间隔”排序后,仍然是“Dk-间隔”有序的
增量元素不互质,更多增量序列
希尔排序如此简单,但是关于他的复杂度分析非常难