zoukankan      html  css  js  c++  java
  • [排序算法] 选择排序(2种)

    1.直接选择排序

    【思想】选出剩下的未排序数据中的最小元素与第i个元素交换

    【特点】不稳定

     空间代价:O(1)

     时间代价:O(n^2)

     1 void SelectSort(int Array[], int n)
     2 {
     3     // 依次选出第i小的记录,即剩余记录中最小的那个
     4     for (int i=0; i< n - 1; i ++)
     5     {
     6         // 首先假设记录i就是最小的
     7         int Min = i;
     8         // 开始向后扫描所有剩余记录
     9         for (int j = i + 1; j < n; j++)
    10             // 如果发现更小的记录,记录它的位置
    11             if (Array[j] < Array[Min])
    12                 Min = j;
    13         //将第i小的记录放在数组中第i个位置
    14         swap(Array[i], Array[Min]);
    15     }
    16 }

    2.堆排序

    【思想】基于最大推来实现,效率更高。堆排序的基本思想是:首先将n个记录按关键码建成堆(初始堆),将堆顶元素与最后一个元素交换,然后将剩余的元素调整成堆...如此反复,便得到了一个按关键码有序的序列。

    可参考我整理的最大堆的类实现http://www.cnblogs.com/lca1826/p/6590864.html

    【特点】不稳定

     空间代价:O(1)

     时间代价:O(nlogn)

     1 /*
     2 堆排序
     3 (1)用大根堆排序的基本思想
     4  ① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
     5  ② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,
     6     由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key
     7  ③ 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。
     8     然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,
     9     由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n- 2].keys≤R[n-1..n].keys,
    10     同样要将R[1..n-2]调整为堆。
    11     ……
    12     直到无序区只有一个元素为止。
    13 
    14 (2)大根堆排序算法的基本操作:
    15  ① 初始化操作:将R[1..n]构造为初始堆;
    16  ② 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。
    17 
    18  注意:
    19  ①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。
    20  ②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。
    21    堆排序和直接选择排序相反:在任何时刻,堆排序中无序区总是在有序区之前,
    22    且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。
    23 */
    24 #include <iostream>
    25 using namespace std;
    26 
    27 void HeapAdjust(int SortData[],int StartIndex, int Length)
    28 {
    29     int MaxChildIndex = 2*StartIndex + 1;
    30     while(MaxChildIndex < Length)
    31     {
    32         //比较左子树和右子树,记录最大值的j
    33         if((MaxChildIndex < Length - 1) && (SortData[MaxChildIndex] < SortData[MaxChildIndex + 1])){
    34             MaxChildIndex ++;
    35         }
    36         if(SortData[StartIndex] < SortData[MaxChildIndex])
    37         {
    38             //交换i与j位置的数据
    39             int temp = SortData[StartIndex];
    40             SortData[StartIndex] = SortData[MaxChildIndex];
    41             SortData[MaxChildIndex] = temp;
    42             //堆被破坏,重新调整
    43             StartIndex = MaxChildIndex;
             MaxChildIndex = 2*StartIndex + 1;
    44 } 45 else break; 46 } 47 return; 48 } 49 50 //堆排序 51 void HeapSortData(int SortData[], int Length) 52 { 53 int i=0; 54 55 //将SortData[0,Lenght-1]建成大根堆 56 for (i=Length/2-1; i>=0; i--) 57 { 58 HeapAdjust(SortData, i, Length); 59 } 60 61 for (i=Length-1; i>0; i--) 62 { 63 //与最后一个记录交换 64 int tmpData =SortData[0]; 65 SortData[0] =SortData[i]; 66 SortData[i] =tmpData; 67 //将SortData[0..i-1]重新调整为大根堆 68 HeapAdjust(SortData, 0, i); 69 } 70 return; 71 } 72 73 int main() 74 { 75 int array[6] = {10, 15, 56, 25, 30, 70}; 76 HeapSortData(array, 6); 77 for (int index = 0; index != 6; ++index) 78 { 79 cout<<array[index]<<" "; 80 } 81 cout<<endl; 82 return 0; 83 }
  • 相关阅读:
    HDU 1754线段树基本操作,建树,更新,查询
    用第三方下载工具下载官方XCode独立安装包的方法
    解决Windows平台通过cURL上传APP到蒲公英pgyer平台时无法使用中文升级描述的问题
    Cygwin 版本的 Curl 安装,提取,使用笔记
    Android Gradle 引用本地 AAR 的几种方式
    VM虚拟机快照还原效果实现方式
    插入中文错误ERROR 1406 (22001): Data too long for column 'name' at row 1
    mysql初始化默认为空的密码修改
    性能测试学习计划(转)
    context-param和init-param区别
  • 原文地址:https://www.cnblogs.com/lca1826/p/6486261.html
Copyright © 2011-2022 走看看