选择排序是一种以重复选择为思想的排序算法.其中直接选择排序是最简单的一种.
直接选择排序:
算法:
假设有一个A[n]的数组,首先找到最小的元素,将其保存在A[1]中,然后找到剩下的n - 1个元素中的最小元素,放在A[2]中,重复此过程直到找到第二大的元素.
代码:
#include <stdio.h>
const int MAX = 10;
void selectionSort(int *A)
...{
int i, j, k, temp;
for(i = 0; i < MAX - 1; i++)
...{
k = i;
for(j = i + 1; j < MAX; j++)
if(A[j] < A[k])
k = j;
if(k != i)
...{
temp = A[k];
A[k] = A[i];
A[i] = temp;
}
}
}

int main()
...{
int A[MAX];
int i;
int nums = MAX;
printf("Please input %d numbers: ", nums);
for(i = 0; i < MAX; i++)
scanf("%d", &A[i]);
selectionSort(A);
for(i = 0; i < MAX; i++)
printf("%d ", A[i]);
return 0;
}
可以看出元素交换的最小次数是0,最大是n - 1.同时交换过程中的元素赋值次数介于0与3(n - 1)之间,还有关键字的比较次数,均为n(n - 1) / 2,所以算法的时间复杂度为O(n2).
选择排序的主要操作是元素之间的关键字比较.因此,改进直接选择排序可以从减少比较的次数入手.
有这样的一个定理:
任何以比较元素对偶为基础的在n个元素中寻找极大者的算法,必须至少做n - 1次的比较.(<<计算机程序设计艺术>>)
不过仔细思考一下就可以明白,这个定理仅适用于头一个选择步骤.我们可以用模仿体育比赛选拔的方式来改进直接选择算法,既随后的选择可以用头一次选择后产生信息来进行.
锦标排序:
锦标排序又叫树型选择排序,通过这个名字可以清楚的理解到锦标排序的样子.
算法:
我们可以用有n个叶子节点的满二叉树来组织这个算法.
首先让元素两两之间进行比赛,当叶子节点的优胜者向上一个分枝移动以后,用一个特殊的标志位来代替原来它所出的位置(比如-∞).当一个非叶子节点的优胜者向上移动的时候,他原来的位置由它下面节点的优胜者来填补,如此循环往复.
分析:
当一个满二叉树有n个叶子节点的时候,他的深度应当是log2n + 1,所以出了最小(大)的关键字以外,每选择一个次小的关键字仅需要进行log2n次的比较,因此它的时间复杂度就是O(nlog2n).
但是锦标排序的缺点很明显,需要额外的辅助空间,而且选择最值的时候有多余的比较.堆排序同样做为一种选择排序很好的解决了这个问题.
本文介绍了选择排序的基本原理及其实现方式,并深入探讨了直接选择排序算法的时间复杂度。此外,还提出了一种改进版的选择排序——锦标排序,详细阐述了其算法流程及其优势,包括如何利用满二叉树组织数据并降低比较次数。
1266

被折叠的 条评论
为什么被折叠?



