第1个回答 2016-06-02
1.选择排序
定义:首先,选出数组中最小的元素,将它与数组中第一个元素交换。然后找出次小的元素,并将它与数组中第二个元素交换。按照这种方法一直进行下去,直到整个数组排完序。
交换次数:N-1
缺点:运行时间对文件已有序的部分依赖较少,从文件中选出最小元素的每一遍操作过程,并没有给出下一遍要找的最小元素的位置的相关消息。例如,该程序对已排好序的文件或各元素都相同的元素文件与对随机排列的文件排序所花的时间基本相同。
适用性:对于元素比较大,关键字又比较小的文件,应该选择该方法,而其他算法移动数据的步数都比选择排序更多。
sc(source code):
template <typename T, typename Compare>
void SelectSort(vector<T> & arr, Compare cp)
{
Display(arr, "before SelectSort:");
for (size_t i=0; i<arr.size(); ++i) {
size_t m = i;
for (size_t j=i+1; j<arr.size(); ++j) {
if ( !cp(arr[m], arr[j]) ) {
m = j;
}
}
if (m != i) {
swap(arr[i], arr[m]);
}
Display(arr, i);
}
}
2.插入排序(摘自:
插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
算法描述:
一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:
从第一个元素开始,该元素可以认为已经被排序
取出下一个元素,在已经排序的元素序列中从后向前扫描
如果该元素(已排序)大于新元素,将该元素移到下一位置
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
将新元素插入到该位置中
重复步骤2
如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。
算法复杂度:
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数减去(n-1)次。平均来说插入排序算法复杂度为O(n2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。
sc:
template <typename T, typename Compare>
void InsertSort(vector<T>& arr, Compare cp)
{
Display(arr, "before InsertSort:");
for(size_t i=1; i<arr.size(); ++i) {
T temp = arr[i];
for(size_t j=i ; j>0 && !cp(temp, arr[j-1]) ; --j) {
arr[j] = arr[j-1];
arr[j-1] = temp;
Display(arr, "----");
}
Display(arr, i);
}
}本回答被网友采纳