C# 算法之堆排序

偷图
在这里插入图片描述

堆排序(Heap Sort)

堆介绍

想要了解堆排序,就必须得先知道堆是什么:
堆通常是一个可以被看做一棵完全二叉树的数组对象。
完全二叉树是指:
1.每一个节点最多只有两个子节点(二叉树)
2.只有上一层满了,才能有下一层
3.只能从从左到右依次排序
堆有两种:
大顶堆:每个父节点都大于子节点(比如50大于45,40)
小顶堆:每个父节点都小于子节点(比如10小于20,15)

在这里插入图片描述

堆排序逻辑

简单来讲,堆排序的要点在于(以下特指从小到大排序):
1.构造大顶堆,即将最大数字上浮到最上面的根节点上
2.将最大值取出放置最后
3.调整堆至大顶堆(就是重复第一步)

所以自然最重要的是如何构造大顶堆:

再偷图
在这里插入图片描述

代码

总代码

        public int[] HeapSort3(int[] array)
        {
             //获取最大数组下标
            int heapSize = array.Length - 1;

            //for循环
            for (int i = heapSize; i >= 0; i--)
            {
                //构建大顶堆
                BuilderMaxHeap3(array, i);
                //将第一个数据与最后一个数据进行调整
                swap(array, 0, i);
            }
            return array;
        }

构建大顶堆

        private void builderMaxHeap(int[] array, int heapSize)
        {
            //获取最后一个非叶子节点(因为是索引,必须加+1)
            int parser = (int)Math.Floor((double)((heapSize + 1) / 2 - 1));
            //for循环,从下往上依次构建
            for (int i = parser; i >= 0; i--)
            {
                //调整大顶堆
                MaxHeapify3(array, i, heapSize);
            }
        }

此处是因为用的是索引,所以需要在"n/2-1"的基础上,n需要加一

调整堆(大数上浮)

        private void MaxHeapify3(int[] array, int index, int heapSize)
        {
            var iMax = index;
            var iLeft = 2 * index + 1;//index节点的左子节点
            var iRight = 2 * (index + 1);//index节点的右子节点

            //如果左节点大于index节点,则大值为左节点
            if (iLeft <= heapSize && array[index] < array[iLeft])
            {
                iMax = iLeft;
            }
            //如果右节点大于index节点,则大值为右节点
            if (iRight <= heapSize && array[iMax] < array[iRight])
            {
                iMax = iRight;
            }
            //大值不为index节点,则交换,并重新调整
            if (iMax != index)
            {
                swap(array, iMax, index);
            }
        }

偷图源

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值