堆排序原理简记,及C++实现。

堆排序要用到完全二叉树的概念。完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当

其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
这里写图片描述
如上也为一个完全二叉树。

堆是一棵顺序存储的完全二叉树。

其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。

其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。

举例来说,对于n个元素的序列{R0, R1, … , Rn}当且仅当满足下列关系之一时,称之为堆:

(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)

(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)

其中i=1,2,…,n/2向下取整;

这里写图片描述

如上,左图为小根堆,虽然说是完全二叉树,但是其存储结构依然为如图所示的堆存储。

算法关键:

1.heapinsert()函数,在一个大根堆上插入一个数,使其形成新的大根堆。

2.heapify()函数,当某个Index位置的值更换时,重新让其变为大根堆。

算法流程:

1.用heapinsert()函数,将所输入数组arr[]变为大根堆形式。

2.将大根堆的根节点与arr[heapsize]交换,即将根节点移出该二叉树,并用heapify()使交换后的结构仍然为大根堆。

3.重复2操作。直到heapsize=1。

该过程即是通过大根堆的形式,不断将其最大值(根节点)放置在数组尾部,以达到排序目的。

算法复杂度:

1.heapinsert()部分,为log1+log2+“`+logN;故为O(N)的复杂度;

2.堆的存储表示是顺序的。因为堆所对应的二叉树为完全二叉树,而完全二叉树通常采用顺序存储方式。当想得到一个序列中第k个最小的元素之前的部分排序序列,最好采用堆排序。因为堆排序的时间复杂度是O(n+klog2n),若k≤n/log2n,则可得到的时间复杂度为O(n)。

C++代码如下。

此处仅为学习简记,若需详细请参考。其中有JAVA实现

https://mp.weixin.qq.com/s?__biz=MzI2NjA3NTc4Ng==&mid=2652080333&idx=1&sn=0940ed41b6ef55f36092c38dec914307&chksm=f1748328c6030a3e871e6ddc36cbf99c0b4732bae68c3fade35047c3fdcba3ff32cd35951de7&mpshare=1&scene=23&srcid=0824Ukb3ePyc4drFMJYP4sXV#rd

#include "stdafx.h"
#include<iostream>;
using namespace std;



void heapinsert(int a[], int index)
{
    while (a[index] > a[(index - 1) / 2])
    {
        swap(a[index], a[(index - 1) / 2]);
        index = (index - 1) >> 1;
    }

}



void heapify(int a[], int index, int heapsize)
{
    int left = index * 2 + 1;
    while (left < heapsize)
    {
        int largest = left + 1 < heapsize && a[left + 1] > a[left]
            ? left + 1 : left;
        largest = a[largest] > a[index] ? largest : index;
        if (largest == index) break;
        swap(a[largest], a[index]);
        index = largest;
        left = index * 2 + 1;
    }

}


void heapsort(int a[],int heapsize)
{
    if (heapsize < 2) return;
    for (int i = 0; i < heapsize; i++) {
        heapinsert(a, i);
    }
    swap(a[0], a[--heapsize]);
    while (heapsize > 0)
    {
        heapify(a, 0, heapsize);
        swap(a[0], a[--heapsize]);
    }

}


int main()
{
    int as[] = {1,3,2,5,5,4,7,8,5};
    int n = 9;
    heapsort(as,n);
    for (int i = 0; i < n; i++) cout << as[i] << endl;
}

快捷键-加粗 按按按按按按按按按按按按按按按按按按按按按按按按按按Ctrl + B -斜体 CTRL + I -引用 CTRL + Q - 插入链接’按用菜单调用插入代码’打字代理’打样代理’按下按Ctrl按住Ctrl按用键Ctrl按住Ctrl按住按按代代代代代代代代代代代键键+ K -插入图片按按按按按按按按按按按按按CTRL + G -提升标题 Ctrl + H键键键键键键键键键键键键键键键键用这个- 有机列表按钮+键盘用于键盘按键+键盘键用键-无序列表按按按按按按CTRL + U. -横线按按Ctrl + R键键键键键键键键键-撤销按按按按按按Ctrl + Z. -重做按按按按按按按按按Ctrl + Y ` ##减价及扩展>降价是一种轻量级标记语言,它允许人们使用易读易写的,然后转换成格式丰富的HTML页面- -

离线写博客即使用户在没有网络的情况下,也可以通过本编辑器离线写(直接在曾经使用过的浏览器中输入[write.blog.csdn.net/mdeditor](HTTP:// write) )))))。)。blog.csdn.net / mdeditor)即可。* Markdown编辑器使用浏览器离线存储将内容保存在本地。用户写博客的过程中,内容实时保存在浏览器缓存中,在用户关闭浏览或者其他异常情况下,内容不用户可以选择<我类=“icon-disk”> 把正在写的博客保存到服务器草稿箱,即使换浏览器或者清除缓存,内容也不会丢失。> 注意:虽然浏览器存储大部分时候都比较可靠,但为了你的数据安全,在联网后,*请务必及时发表或者保存到服务器草稿箱* *。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值