八大排序总结(7)——堆排序(Bubble Sort)(c语言实现)

>>>八大排序总结(1)——冒泡排序(Bubble Sort)(c语言实现)<<<

>>>八大排序总结(2)——选择排序(Selection Sort)(c语言实现)<<<

>>>八大排序总结(3)——插入排序(Insertion Sort)(c语言实现)<<<

>>>八大排序总结(4)——快速排序(Quick Sort)(c语言实现)<<<

>>>八大排序总结(5)——归并排序(Merge Sort)(c语言实现)<<<

>>>八大排序总结(6)——希尔排序(Shell Sort)(c语言实现)<<<

>>>八大排序总结(8)——线性时间复杂度的排序(桶排序,基数排序,计数排序)【用空间换时间】(c语言实现)<<<

>>>八大排序 时间复杂度,空间复杂度,稳定性的比较<<<


目录

堆排序(Bubble Sort)基本思想

原理

时间,空间复杂度与算法稳定性

代码+分析


堆排序(Bubble Sort)基本思想

堆排序(英语:Heapsort)是指利用这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作:

  • 最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点

  • 创建最大堆(Build Max Heap):将堆中的所有数据重新排序

  • 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算 

 


原理

 首先,我们要构建最大堆

             [1] 从最大的非叶节点(设为Key[i])开始,往下进行调整,如果子孩子节点Key[2*i+1]和Key[2*i+2]较大的值比Key[i]的值大,则,交换该节点Key[i]与子节点中较大的节点。然后 以交换后的子节点作为当前节点,往下进行调整,直到遇到叶节点;

             [2] 最大非叶节点Key[i]调整完毕后,对节点Key[i-1]进行往下调整,直到出现叶节点;不断重复此过程,直到对根节点往下调整完毕;

            下面是建大顶堆的实例:待排序数组为[5 16 3 20 17 4]

 

 建好最大堆后就可以进行堆排序了,如下图所示


时间,空间复杂度与算法稳定性

1.时间复杂度:

最坏情况下时间复杂度:O(NlogN)

平均时间复杂度:O(NlogN)

2.空间复杂度:O(1)

3.稳定性:不稳定


代码+分析

//堆调整,构建大顶堆,arr[]是待调整的数组,i是待调整的数组
//元素的位置,length是数组的长度
void HeapAdjust(int arr[], int i, int length)
{
    int Child;
    int temp;
    for(;2 * i + 1 < length; i = Child)
    {
        //子节点的位置 = 2 * (parent(父结点)) + 1
        Child = 2 * i + 1;
        //得到子结点中较大的结点
        if(Child < length - 1 && arr[Child + 1] > arr[Child])
        ++Child;
        //如果较大的子结点大于父结点那么把较大的子结点往上移动
        //替换它的父结点
        if(arr[i] < arr[Child])
        {
            temp = arr[i];
            arr[i] = arr[Child];
            arr[Child] = temp;
        }
        else
            break;
    }
}
//堆排序算法
void heap_sort(int arr[], int length)
{
    int i;
    //调整序列的前半部分元素,调整完之后第一个元素
    //是序列的最大元素,length/2-1是最后一个非叶子结点
    for(i = length/2 - 1; i >= 0; --i)
        HeapAdjust(arr, i, length);
    //从最后一个元素开始对序列进行调整,不断的缩小调整
    //的范围直到第一个元素
    //循环里是把第一个元素和当前的最后一个元素交换
    //保证当前的最后一个位置的元素是现在这个序列的最大的
    //不断的缩小调整heap的范围,每一次调整完毕保证第一个
    //元素是当前序列的最大的元素
    for(i = length - 1; i > 0; --i)
    {
        arr[i] = arr[0]^arr[i];
        arr[0] = arr[0]^arr[i];
        arr[i] = arr[0]^arr[i];
        //此处通过异或运算交换arr[i]与arr[0]的值
        HeapAdjust(arr, 0, i);    //递归调整
    }
}

欢迎大家评论指正,谢谢◕‿◕

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值