C# 常用排序算法——选择排序:堆排序

1.可将一维数组视为一棵完全二叉树

2.思想:输出堆顶极值,使剩余(n-1)个元素重新成堆,得到下次极值,反复,直到得到所有序列

        static void HeapCompare(int[] array, int nowIndex, int arrayLength)
        {
            //通过传入的索引 得到它对应的左右叶子节点的索引
            //可能算出来的会溢出数组的索引 我们一会再判断
            int left = 2 * nowIndex + 1;
            int right = 2 * nowIndex + 2;
            //用于记录较大数的索引
            int biggerIndex = nowIndex;
            //先比左 再比右
            //不能溢出 
            if( left < arrayLength && array[left] > array[biggerIndex])
            {
                //认为目前最大的是左节点 记录索引
                biggerIndex = left;
            }
            //比较右节点
            if( right < arrayLength && array[right] > array[biggerIndex] )
            {
                biggerIndex = right;
            }
            //如果比较过后 发现最大索引发生变化了 那就以为这要换位置了
            if( biggerIndex != nowIndex )
            {
                int temp = array[nowIndex];
                array[nowIndex] = array[biggerIndex];
                array[biggerIndex] = temp;

                //通过递归 看是否影响了叶子节点他们的三角关系
                HeapCompare(array, biggerIndex, arrayLength);
            }
        }
        //第二步:构建大堆顶
        static void BuildBigHeap(int[] array)
        {
            //从最大的非叶子节点索引 开始 不停的往前 去构建大堆顶
            for (int i = array.Length / 2 - 1; i >= 0 ; i--)
            {
                HeapCompare(array, i, array.Length);
            }
        }
        //第三步:结合大堆顶和节点比较 实现堆排序 把堆顶不停往后移动
        static void HeapSort(int[] array)
        {
            //构建大堆顶
            BuildBigHeap(array);
            //执行过后
            //最大的数肯定就在最上层

            //往屁股后面放 得到 屁股后面最后一个索引
            for (int i = array.Length - 1; i > 0; i--)
            {
                //直接把 堆顶端的数 放到最后一个位置即可
                int temp = array[0];
                array[0] = array[i];
                array[i] = temp;

                //重新进行大堆顶调整
                HeapCompare(array, 0, i);
            }
        }

复杂度分析

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值