堆排序(heapsort)是一种比较快速的排序方式,它的时间复杂度为O(nlgn),并且堆排序具有空间原址性,任何时候只需要有限的空间来存储临时数据。我将用c++实现一个堆来简单分析一下。
堆排序的基本思想为:
1、升序排列,保持大堆;降序排列,保持小堆;
2、建立堆之后,将堆顶数据与堆中最后一个数据交换,堆大小减一,然后向下调整;直到堆中只剩下一个有效值;
下面我将简单分析一下:
第一步建立堆:
1、我用vector顺序表表示数组;
2、用仿函数实现大小堆随时切换,实现代码复用;
3、实现向下调整算法,时间复杂度为O(lgn);
下面是我用某教材中的一个建最小堆的过程图,希望能更直观一些:
为了保证复用性,用仿函数重载了(),下面是复用的向下调整算法:
void _AdjustDown(int root,int size) { Camper camper; //仿函数 int parent = root; int child = parent * 2 + 1; while (child <= size) //保证访问不越界 { if (child < size && camper(_vec[child+1] , _vec[child])) //保证存在右子树、同时判断右子树是否大于或小于左子树 { child++; } if (camper(_vec[child], _vec[parent])) { swap(_vec[parent], _vec[child]); parent = child; child = parent * 2 + 1; } else { break; } } }
排序算法思想:
1、将堆顶数据与堆中最后一个数据交换;
2、堆大小减一,然后调用向下调整算法;
3、结束条件:堆中剩下一个有效值;
排序算法实现:
void Sort() { size_t size = _vec.size(); //数据数量 while (size > 1) { swap(_vec[0], _vec[size - 1]); size--; _AdjustDown(size); } }
仿函数的实现:
template<class T> struct Greater //大于 { bool operator ()(const T& l, const T& p) { return l > p; } }; template<class T> struct Less //小于 { bool operator () (const T&l, const T& p) { return l < p; } };
完整的代码实现:
#include<iostream> using namespace std; #include<vector> template<class T> struct Greater //大于 { bool operator ()(const T& l, const T& p) { return l > p; } }; template<class T> struct Less //小于 { bool operator () (const T&l, const T& p) { return l < p; } }; template<class T,class Camper> class HeapSort //建大堆 { public: HeapSort() {} HeapSort(T* arr, size_t n) { _vec.reserve(n); if (arr != NULL) { for (size_t i = 0; i < n; i++) { _vec.push_back(arr[i]); } } _AdjustDown(_vec.size()); } void Sort() { size_t size = _vec.size(); //数据数量 while (size > 1) { swap(_vec[0], _vec[size - 1]); size--; _AdjustDown(size); } } void Print() { for (size_t i = 0; i < _vec.size(); i++) { cout << _vec[i] <<" "; } cout << endl; } protected: void _AdjustDown(int size) { int parent = (size - 2) / 2; while (parent >= 0) { _AdjustDown(parent, size - 1); parent--; } } void _AdjustDown(int root,int size) { Camper camper; //仿函数 int parent = root; int child = parent * 2 + 1; while (child <= size) //保证访问不越界 { if (child < size && camper(_vec[child+1] , _vec[child])) //保证存在右子树、同时判断右子树是否大于或小于左子树 { child++; } if (camper(_vec[child], _vec[parent])) { swap(_vec[parent], _vec[child]); parent = child; child = parent * 2 + 1; } else { break; } } } private: vector<T> _vec; };
测试用例代码:
void TextSort() { int a[] = { 10, 11, 13, 12, 16, 18, 15, 17, 14, 19 }; HeapSort<int,Greater<int>> h(a, sizeof(a) / sizeof(a[0])); h.Print(); h.Sort(); h.Print(); }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
本文向大家介绍C语言 数据结构堆排序顺序存储(升序),包括了C语言 数据结构堆排序顺序存储(升序)的使用技巧和注意事项,需要的朋友参考一下 堆排序顺序存储(升序) 一: 完全二叉树的概念:前h-1层为满二叉树,最后一层连续缺失右结点! 二:首先堆是一棵全完二叉树: a:构建一个堆分为两步:⑴创建一棵完全二叉树 ⑵调整为一个堆 (标注:大根堆为升序,小根堆为降序) b:算法描述:①创
本文向大家介绍C语言数据结构之堆排序源代码,包括了C语言数据结构之堆排序源代码的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言堆排序源代码,供大家参考,具体内容如下 1. 堆排序 堆排序的定义及思想可以参考百度百科: 用一句概括,堆排序就是一种改进的选择排序,改进的地方在于,每次做选择的时候,不单单把最大的数字选择出来,而且把排序过程中的一些操作进行了记录,这样在后续排序中可以
本文向大家介绍使用C#实现数据结构堆的代码,包括了使用C#实现数据结构堆的代码的使用技巧和注意事项,需要的朋友参考一下 一、 堆的介绍: 堆是用来排序的,通常是一个可以被看做一棵树的数组对象。堆满足已下特性: 1. 堆中某个节点的值总是不大于或不小于其父节点的值 任意节点的值小于(或大于)它的所有后裔,所以最小元(或最大元)在堆的根节点上(堆序性)。堆有大根堆和小根堆,将根节点最大的堆
本文向大家介绍C#数据结构之堆栈(Stack)实例详解,包括了C#数据结构之堆栈(Stack)实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#数据结构之堆栈(Stack)。分享给大家供大家参考,具体如下: 堆栈(Stack)最明显的特征就是“先进后出”,本质上讲堆栈也是一种线性结构,符合线性结构的基本特点:即每个节点有且只有一个前驱节点和一个后续节点。 相对前面学习过的顺序表、
试图实现一个cpp程序,该程序在不使用类的情况下根据年份对出版物列表进行排序。 假设这些信息在一个文本文件中,每个文件由一个选项卡分隔: 在这个函数中,我必须将这些数据存储在一个列表中(最好是向量) 我的问题是如何将这些数据存储到一个向量中,以便在后面的函数中,我可以根据年份对整个向量进行排序?此外,我需要迭代,看看是否有不止一行信息。
我是C语言的新手,正在尝试根据另一个向量中的值对向量进行排序。我试图通过创建结构向量并使用STL对结构向量进行排序来实现这一点。结构有两个数据项,一个是CustomType,另一个是int。我希望按int字段的降序排序,因此包含一个布尔运算符重载,以便能够使用STL排序(算法)。 在函数中使用对CustomType向量和初始未初始化的int向量的引用构造结构,并将它们组合成结构向量。int的值是通