博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
堆排序 c 实现 及 c++模板实现
阅读量:6653 次
发布时间:2019-06-25

本文共 3160 字,大约阅读时间需要 10 分钟。

(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:

  •   1.堆中某个节点的值总是不大于或不小于其父节点的值;

  •   2.堆总是一棵完全树。

将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。

堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。

" ki<=k2i,ki<=k2i+1;或ki>=k2i,ki>=k2i+1.(i=1,2,…,[n/2])"

若将和此次序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

 

堆的基本思想其实也很简单,就是三个元素(父节点和俩个子节点)之间比较大小,若是最大堆,就是最大的那个数移到父节点;若是最小堆,就把最小的那个数移到父节点那个位置。

最小堆最大堆

对一个序列都经过这样的处理,序列的第一个就是最小(最小堆)的元素,然后把第一个元素移除,把最后一个元素复制过来,或者把第一个元素和最后一个元素交换,然后再对剩下的元素就行处理,直到整个序列处理完,序列就是一个有序的了。

对a[10] = {4, 1, 3, 5, 2, 6, 7, 0, 9, 8}进行一次处理:

1.                                                                                                         2.

3.                                                                                                           4.

5.

堆排序的大致过程就这样,然后就是0和8交换位置,再把总数减1,在进行上述过程。

c实现:

#include
#include
void fixDown(int *a, int numTotal, int pos){ int compareIndex = pos * 2 + 1;//左字节点的下标 while (2 * pos + 1 < numTotal) { compareIndex = 2 * pos + 1; if ((compareIndex + 1 < numTotal) && (a[compareIndex] > a[compareIndex + 1])) //左右子节点的最小的那个数的下标 compareIndex += 1; /* *父节点大于子节点的话,就交换,不然就break */ if (a[pos] > a[compareIndex]) { int temp = a[pos]; a[pos] = a[compareIndex]; a[compareIndex] = temp; } else break; pos = compareIndex;//向下继续比较 }}int main(void){ int a[10] = {4, 1, 3, 5, 2, 6, 7, 0, 9, 8}; int numTotal = sizeof(a) / sizeof(int); int i; /* *建一个堆 */ for (i = (numTotal - 1) / 2; i >= 0; i--) { fixDown(a, numTotal, i); } while (numTotal > 0) { /* *交换第一个和最后一个元素 */ int temp = a[0]; a[0] = a[numTotal - 1]; a[numTotal - 1] = temp; fixDown(a, --numTotal, 0); } for (i = 0; i < 10; i++) { printf("%d ", a[i]); } printf("\n"); return 0;}

c++模板实现:

#include
#include
#include
#include
using namespace std;template
void adjust_heap(Randomiterator begin, Randomiterator end, Randomiterator pos, Comparator comp) { typedef typename std::iterator_traits
::difference_type diff_t; const diff_t numTotal = distance(begin, end); diff_t position = distance(begin, pos); while ((2 * position + 1 < numTotal)) { diff_t compIndex = 2 * position + 1; if ((compIndex + 1 < numTotal) && (comp(begin[compIndex], begin[compIndex + 1]))) compIndex += 1; if (comp(begin[compIndex], begin[position])) break; std::swap(begin[compIndex], begin[position]); position = compIndex; }}template
void Heapsort(Randomiterator begin, Randomiterator end, Comparator comp){ typedef typename std::iterator_traits
::difference_type diff_t; diff_t numTotal = distance(begin, end); if (begin == end || begin + 1 == end) return; Randomiterator itr; for (itr = begin + (numTotal - 1)/2; itr >= begin; itr--) adjust_heap(begin, end, itr, comp); while (end - begin > 0) { std::swap(begin[0], begin[distance(begin, end - 1)]); adjust_heap(begin, --end, begin, comp); }}template
void heapsort(Randomiterator begin, Randomiterator end) { Heapsort(begin, end, std::less
::value_type>());}int main(void){ int a[10] = {4, 1, 3, 5, 2, 6, 7, 0, 9, 8}; heapsort(&a[0], &a[10]); int i; for (i = 0; i < 10; i++) cout << a[i] << ' '; cout << endl;}

转载于:https://www.cnblogs.com/lutianba/p/3268560.html

你可能感兴趣的文章
JAVA多线程与多进程
查看>>
复制的文本加上版权信息
查看>>
二分查找
查看>>
path,classpath
查看>>
放大电路分析方法二
查看>>
[洛谷P5105]不强制在线的动态快速排序
查看>>
[洛谷P4735]最大异或和
查看>>
跟我学算法-贝叶斯拼写检查器
查看>>
Android使用动态代理搭建网络模块框架
查看>>
手写Function.bind函数
查看>>
这么多开源框架,该用哪个好?
查看>>
httpSecurity
查看>>
【Android】21.1 画板资源
查看>>
Codeforces 374D - Inna and Sequence
查看>>
4-4 链式表的按序号查找 (10分)
查看>>
[POJ 2728]Desert King(0-1分数规划/最优比率生成树)
查看>>
JWT_token
查看>>
提取文件某列的小脚本
查看>>
12. php and Ajax
查看>>
Sql 查询过慢,尝试重建索引
查看>>