C++实现堆排序

C++实现堆排序,第1张

概述本文章向大家介绍C++实现堆排序,主要包括C++实现堆排序使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

了解什么是堆

什么是堆,堆的定义是:n个元素的序列,{k1,k2,k3,…,kn},当且满足如下关系式,称为堆。


ki < k2i && ki < k2i+1

ki > k2i && ki > k2i+1


如下所示:

如何利用堆来排序

将一个无序序列建成堆

堆看作是一个完全二叉树,堆就完全满足二叉树的五个性质,如果不清楚的可以去看看二叉树的性质。


从堆中最后一个非终点[n / 2] 个元素,向前慢慢筛选,一直到[ 1 ],

如何输出堆顶元素后,调整剩余元素为堆

如果是每一个父节点都对左右孩子节点打的,就是大根堆,可知,堆顶的元素就是最大的,相反的话,就是小根堆,堆顶元素就是最小的。


大根堆用来做顺序,每次将堆顶的元素,和堆尾的元素交换,然后将剩下的节点变成大根堆,最后一个元素就变成了最大的。小根堆相反。

合适的代码实现

数据的基本类型

采用自定义结构体类型,将别的记录都简化,只留下关键部分。类似数据库中的一条记录,中只保留关键字,依据关键字来排序。

typedef struct

{

int key;

// float name;

// elemtype anothing;

} recnode;

定义MySort类来实现。运算符重载实现了,可以直接输入和输出的功能。中间还没注意多写了一个插入拍寻的函数。当然现在的重点是堆排序了。

两个函数,Shift, 和 HeapSort。

class MySort

{

private:

recnode rec[MAXSIZE];

int len;

public:

voID SeleSort(); // 选择排序

voID Shift(int i,int m); // 堆排序的建立大顶碓的函数

voID HeapSort(); // 堆排序

frIEnd ostream &operator<<(ostream &,const MySort &); // 输入

frIEnd istream &operator>>(istream &,MySort &); // 输出

};

两个函数,Shift, 和 HeapSort。

说一说对Shift的理解,Shift有两个参数,i 和 m , i 是根节点的编号 , (父节点的编号),m 是最后一个节点的编号。从 i 节点往下,层次筛选,找到比 i 节点左右孩子节点大的节点就将 i 节点 的值换成 大的节点。依次向下。

voID MySort::Shift(int i,int m){

// i 是根节点的编号 , (父节点的编号)

// m 是最后一个节点的编号

int j;

recnode temp = rec[i];

j = 2 * i; // j 是左孩子

while (j <= m) {

// j 是左右都有节点的 较大值

// 为什么不是 j <= m 呢,因为当 j = m 时,只有一个节点

if ( j < m && rec[j].key < rec[j + 1].key)

j++;

if (temp.key < rec[j].key) {

rec[i] = rec[j];

i = j;

j = 2 * i;

}

else break;

}

rec[i] = temp;

}

然后是HeapSort函数,为什么第一次循环是从,数组的长度的一半开始呢?堆可以看做事一个完全二叉树,二叉树的性质中有,长度为 N 完全二叉树, 节点标号为 N/2的元素,一定在上一层,即一定是度为 0 或 1 的节点。

利用Shift(N/2,N)一定将此节点完美的建成一个大小根堆。循环向上一直到堆的根节点,可以将以个无序的数组建成大小根堆。

由于根堆的性质,堆顶元素一定是最大或者最小的,将堆顶的元素和最后一个元素互换,那么堆最后一个元素一定也是最大或者最小的,然后将剩余的元素(除堆最后一个元素),重新建成一个大小根堆,第一次筛选完成。然后以此向下即可。

voID MySort::HeapSort(){

int i;

int n = len;

recnode temp;

for( i = n / 2; i >= 1; i--)

Shift(i,n);

for( i = n; i >= 2; i--)

{

temp = rec[1];

rec[1] = rec[i];

rec[i] = temp;

Shift(1,i - 1);

}

}

为了输入输出的方便,利用C++的特性,将运算符重载会方便许多,附上代码。

ostream &operator<<(ostream & output,const MySort &c){

for(int i = 1; i <= c.len; i++)

{

output << c.rec[i].key << " ";

}

output << endl;

return output;

}

istream &operator>>(istream & input,MySort &c){

int i,k = 0;

cout << "输入数据,以空格隔开,0 结束" << endl;

input >> i;·2

while ( i ) {

k++;

c.rec[k].key = i;

input >> i;

}

c.len = k;

return input;

}

主函数调用:

int main(int argc,char const *argv[])

{

MySort a ;

cin >> a;

a.HeapSort();

cout << a ;

return 0;

}

结果如下

总结

以上是内存溢出为你收集整理的C++实现堆排序全部内容,希望文章能够帮你解决C++实现堆排序所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1264621.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存