选择排序
选择排序:
基本思想:
第i趟在n-i+1(i=1,2,…,n-1)个记录中选取关键字最小的记录作为有序序列中的第i个记录 。
1.简单选择排序
2.树形选择排序
3.堆排序
简单选择排序 :
排序过程:
-
首先通过 n –1 次关键字比较,从 n 个记录中找出关键字最小的记录,将它与第一个记录交换。
-
再通过 n –2 次比较,从剩余的 n –1 个记录中找出关键字次小的记录,将它与第二个记录交换。
-
重复上述操作,共进行 n –1 趟排序后,排序结束。
简单选择排序算法描述:
void SelectSort (SqList &L) { // 对顺序表 L 作简单选择排序
for (i = 1; i < L.length; ++ i) {
k = i;
for ( j = i+1; j <= n; j++) if (L.r[j].key < L.r[k].key) k = j;
if (i != k) L.r[i]←→L.r[k]; // 与第 i 个记录交换
}
} // SelectSort
简单选择排序算法分析:
由于存在着不相邻元素之间的互换,因此,简单选择排序是“不稳定的” 。
算法实现共需要进行n-1 次选择,每次选择需要进行n-i次比较(1≤i≤n-1),而每次交换最多需3次移动,因此,总的比较次数 C = n(n-1)/2,总的移动次数 M = 3(n-1)。故其时间复杂度为O(n^2)。
空间效率:O(1)——交换时用到一个暂存单元
简单选择排序的性能分析:
时间效率:O(n^2)
空间效率:O(1)
稳 定 性:不稳定
树形选择排序 **(又称锦标赛排序 **):
基本思想:
与体育比赛时的淘汰赛类似。
首先对 n 个记录的关键字进行两两比较,得到 n/2 个优胜者(关键字小者),作为第一步比较的结果保留下来。然后在这 n/2 个较小者之间再进行两两比较,…,如此重复,直到选出最小关键字的记录为止。
树形选择排序算法描述:
void UpdateTree ( DataNode tree, int i) {
if ( i %2 == 0 )
tree[(i-1)/2] = tree[i-1]; //i偶数, 对手左结点
else
tree[(i-1)/2] = tree[i+1]; //i奇数, 对手右结点
i = (i-1) / 2; //向上调整
while ( i ) { //直到 i==0
if ( i %2 == 0)
j = i-1;
else
j = i+1;
if ( !tree[i].active || !tree[j].active )
if ( tree[i].active )
tree[(i-1)/2] = tree[i]; //i可参选, i上
else
tree[(i-1)/2] = tree[j]; //否则, j上
else //两方都可参选
if ( tree[i].data < tree[j].data )
tree[(i-1)/2] = tree[i]; //关键码小者上
else
tree[(i-1)/2] = tree[j];
i = (i-1) / 2; // i上升到双亲
}
}
树形选择排序算法分析:
•锦标赛排序构成的树是满(完全)二叉树,其深度为 log2n *+*1,其中 n为待排序元素个数。
•时间复杂度:O(nlog2n) —n个记录各自比较约log2n次
•空间效率:O(n) —胜者树的附加内结点共有n’-1个!
•稳定性:稳定 —左右结点相同者左为先