【排序算法】选择排序(C++实现)
2013-03-10 16:01
639 查看
选择排序算法就是每一趟从待排序的记录中选出关键字最小(最大)的记录,顺序放在已排好序的子文件的最后(最前),直到全部记录排序完毕。常见的选择排序有直接选择排序(Selection Sort),堆排序(Heap Sort),平滑排序(Smooth Sort),笛卡尔树排序(Cartesian Sort),锦标赛排序(Tournament Sort),循环排序(Cycle)。下面介绍前两种:
(一)直接选择排序
最差时间复杂度:O(n^2)
最优时间复杂度:O(n^2)
平均时间复杂度:O(n^2)
稳定性:不稳定
直接选择排序(Selection Sort),这是一种简单直观的排序算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的其起始位置,然后再从剩余未排序的序列元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素排序完毕。
算法示意图:
实现代码:
(二)堆排序
最差时间复杂度:O(nlogn)
最优时间复杂度:O(nlogn)
平均时间复杂度:O(nlogn)
稳定性:不稳定
堆排序(Heap Sort),是利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。
通常堆是通过一维数组来实现的,在起始数组为0的情形中,对于节点i:
其左子节点的下标为 (2*i+1);
其右子节点的下标为 (2*i+2);
其父节点的下标为 floor((i-1)/2)。
在堆的数据结构中,堆中的最大值总是位于根节点。堆中定义一下三个操作:
1.最大堆调整(Max Heapify):在假定节点i的左右子节点为根的两颗二叉树都是最大堆的前提下,确保父节点大于子节点,否则下降原父节点,最终使以i为根的子树成为最大堆。
2.创建最大堆(Build Max Heap):将堆所有数据重新排序,对所有非叶子节点调用一次Max Heapify。
3.堆排序(Heap Sort):首先创建最大堆,然后依次将堆的根节点与末节点交换、剔除末节点、对根节点进行最大堆调整,直到堆中的节点数为1,排序结束。
算法示意图:
实现代码:
(一)直接选择排序
最差时间复杂度:O(n^2)
最优时间复杂度:O(n^2)
平均时间复杂度:O(n^2)
稳定性:不稳定
直接选择排序(Selection Sort),这是一种简单直观的排序算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的其起始位置,然后再从剩余未排序的序列元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素排序完毕。
算法示意图:
实现代码:
void SelectSort(int *a, int len) { for (int i=0; i<len-1; i++) { int k = i; int key = a[i]; for (int j=i+1; j<len; j++) { if (a[j]<key) { k = j; key = a[j]; } } if (k!=i) swap(a[i], a[k]); } }
(二)堆排序
最差时间复杂度:O(nlogn)
最优时间复杂度:O(nlogn)
平均时间复杂度:O(nlogn)
稳定性:不稳定
堆排序(Heap Sort),是利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。
通常堆是通过一维数组来实现的,在起始数组为0的情形中,对于节点i:
其左子节点的下标为 (2*i+1);
其右子节点的下标为 (2*i+2);
其父节点的下标为 floor((i-1)/2)。
在堆的数据结构中,堆中的最大值总是位于根节点。堆中定义一下三个操作:
1.最大堆调整(Max Heapify):在假定节点i的左右子节点为根的两颗二叉树都是最大堆的前提下,确保父节点大于子节点,否则下降原父节点,最终使以i为根的子树成为最大堆。
2.创建最大堆(Build Max Heap):将堆所有数据重新排序,对所有非叶子节点调用一次Max Heapify。
3.堆排序(Heap Sort):首先创建最大堆,然后依次将堆的根节点与末节点交换、剔除末节点、对根节点进行最大堆调整,直到堆中的节点数为1,排序结束。
算法示意图:
实现代码:
// 最大堆调整 void MaxHeapify(int *a, int i, int heapSize) { int l = (i+1)*2-1; int r = (i+1)*2; int largest; if (l<=heapSize && a[l]>a[i]) largest = l; else largest = i; if (r<=heapSize && a[r]>a[largest]) largest = r; if (largest!=i) { swap(a[i], a[largest]); MaxHeapify(a, largest, heapSize); } } // 创建最大堆 void BuildMaxHeap(int *a, int len) { for (int i=len/2-1; i>=0; i--) { MaxHeapify(a, i, len-1); } } // 堆排序 void HeapSort(int *a, int len) { BuildMaxHeap(a, len); for (int i=len-1; i>0; i--) { swap(a[0], a[i]); MaxHeapify(a, 0, i-1); } }
相关文章推荐
- 排序算法的C++ && Python实现---选择排序
- C++实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- 排序算法--选择排序C++实现
- 几种常用的排序算法:插入排序、冒泡排序、选择排序的算法及C++实现
- 【排序算法】选择排序(C++实现)
- (一)c++ 和javascript 实现选择排序
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- 【排序算法】分配排序(C++实现)
- 请用Java实现冒泡、插入、选择排序中的任意一个排序算法。
- 选择排序、冒泡排序、插入排序、基数排序、快速排序、归并排序完整C++实现
- 排序算法的C++ && Python实现---希尔排序(缩小增量排序)
- 基本排序算法java实现之选择排序
- 排序算法之四 —— 直接选择排序及交换二个数据的正确实现
- 排序算法的C++实现与性能分析(插入排序、归并排序、快速排序、STOOGE排序、堆排序)
- 关于几个复杂度为N^N的排序算法-冒泡,插入,选择(C++实现)
- [排序算法]:Java实现选择排序和插入排序
- 排序算法之选择排序的思想以及Java实现
- 菜鸟学编程之三:三种最基本排序算法的实现(冒泡排序、选择排序、直接插入排序)
- C++各种常见排序算法 冒泡排序,插入排序,快排序,选择排序,希尔排序
- 排序算法(1) 快速排序 C++实现