堆排序 c++
来源:互联网 发布:mac matlab 安装路径 编辑:程序博客网 时间:2024/05/18 01:04
HeapSort
堆排序是基于堆上的一种排序方法,数据存储的结构是数组,该排序的效率接近排序的下界nlog(n)。
学习堆排序前最好理解掌握以下内容
- 二叉树
- 二叉堆
- 最大堆与最小堆概念
这些概念可以自行百度或谷歌,要留意这里”堆”的概念不同于c++里分配内存所说的堆;
堆排序算法原理如下(基于最大堆而言的):
- 将长度为n的待排序的数组进行堆有序化构造成一个大顶堆(初始最大堆的构建)
- 将根节点与尾节点交换
- 将剩余的n -1个节点重新进行堆有序化
- 重复步骤2,步骤3直至构造成一个有序序列
总而言之,该算法的思想就是最大堆堆顶的最大数取出,将剩余的堆继续调整为最大堆,再次将堆顶的最大数取出,这个过程持续到剩余数只有一个时结束(有点像选择排序那样每次抽出剩余数据的最大值)
第一步:构造堆(Build_Max_Heap):初始化构造堆所形成的二叉树有点类似于完全二叉树,比如如果树的高度为H,那么前H-1层对应的节点数必须是2^(H-1);第H层必须排满树的左边才能排右边。初始化好后堆节点的访问如下:
在数组起始位置为0的情形中:
1. 父节点i的左子节点在位置 2i+1;
2.父节点i的右子节点在位置 2i+2;
3.子节点i的父节点在位置 (i-1)/2;
// 一开始构建好二叉堆(满足最大堆的特征);void buildHeap(int *arr, int size){ for (int i = (size - 1) / 2; i >= 0; i--) { //传入给max_heapify_once 后两个参数为数组的下标; max_heapify_once(arr, i, size - 1); }}
2.最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
void max_heapify_once(int* arr, int start, int end){ int father = start; int son = start * 2 + 1;//左子节点是父子节点的下标*2+1; while (son <= end) { if (son + 1 <= end && arr[son + 1] > arr[son]) //如果右子节点存在并且大于左子节点的情况; { son++; } //如果父节点小于两个子节点中最大者就与其交换,这样就会改变该子节点下面的最大堆结构,所以要继续做下去; else if (arr[father] < arr[son]) { swap(arr[father], arr[son]); father = son; son = father * 2 + 1; } else //如果父子节点比两个子节点都大直接退出函数,因为子节点下面的子节点已满足最大堆的特征 { return; } }}
3.堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整
void heapSort(int* arr, int size){ buildHeap(arr, size); for (int i = size - 1; i > 0; i--) { swap(arr[0], arr[i]); max_heapify_once(arr, 0, i-1); }}
总的代码如下:
#include <iostream>#include <algorithm>using std::swap;using std::cout;using std::endl;using std::cin;void max_heapify_once(int* arr, int start, int end){ int father = start; int son = start * 2 + 1;//左子节点是父子节点的下标*2+1; while (son <= end) { if (son + 1 <= end && arr[son + 1] > arr[son]) //如果右子节点存在并且大于左子节点的情况; { son++; } //如果父节点小于两个子节点中最大者就与其交换,这样就会改变该子节点下面的最大堆结构,所以要继续做下去; else if (arr[father] < arr[son]) { swap(arr[father], arr[son]); father = son; son = father * 2 + 1; } else //如果父子节点比两个子节点都大直接退出函数,因为子节点下面的子节点已满足最大堆的特征 { return; } }}// 一开始构建好二叉堆(满足最大堆的特征);void buildHeap(int *arr, int size){ for (int i = (size - 1) / 2; i >= 0; i--) { //传入给max_heapify_once 后两个参数为数组的下标; max_heapify_once(arr, i, size - 1); }}void heapSort(int* arr, int size){ buildHeap(arr, size); for (int i = size - 1; i > 0; i--) { swap(arr[0], arr[i]); max_heapify_once(arr, 0, i-1); }}int main(){ int n; cout << "Please enter the sum of number you want to sort with heap sort: "; cin >> n; int * arr = new int[n]; for (int i = 0; i < n; i++) { cin >> arr[i]; } heapSort(arr, n); for (int i = 0; i < n; i++) { cout << arr[i] << ' '; } cout << endl; delete[] arr; system("pause"); return 0;}
相关资料推荐:
堆排序维基百科
图解堆排序
堆排序详细讲解
阅读全文
0 0
- 堆排序----C语言
- 堆排序(C#)
- 堆排序C语言
- HeapSort(堆排序 C++)
- c 最大堆排序
- c语言堆排序
- 堆排序(C语言版)
- 堆排序(C++)
- 【c++】堆排序算法
- 堆排序(C#)
- 堆排序(C#)
- 堆排序 ----- C语言
- C算法--堆排序
- 堆排序 C语言版
- C语言堆排序
- 堆排序c语言
- 排序算法 - 堆排序 (C++)
- 堆排序(C\C++)
- scoped详解
- sdut 翻译布尔表达式
- pycharm pep8 代码格式化
- Codeforces897B Chtholly's request
- 从开发小白到音视频专家
- 堆排序 c++
- mysql常用命令整理
- ANR详解
- 莫烦 python Pandas 学习笔记 2017.12.7.11
- linux下 /etc/profile、~/.bash_profile ~/.profile的执行过程
- 数据清洗--DataFrame中的空值处理
- 【第八周】项目4-字符串加密
- javascript 函数方法apply()和call()的共同点和区别
- Servlet 简单实例