• 堆排序


    小堆排序

    堆排序是一种选择排序。

    两个过程:1.初始建堆BuildHeap  2.移除根,重新建堆RebuildHeap

    核心行为是:对于一个 除了根节点外,子树都是小根堆的数据进行根的调节。即AdjustHeap

    AdjustHeap:从root往下都是满足小根堆,那么,需要对root数据进行调节。从root的child找,对比leftChild和rightChild,选两者中较小的和rootVal对比,

            决定是否把child的数据赋给root结点,然后继续从childIndex往下搜,找到一个结点放置rootVal。

    1.初始建堆, 叶子结点是满足小根堆的,从最后一个非叶子结点开始进行AdjustHeap,上溯到Root,初始建堆完成

    2.移除根节点后,把最后一个叶子放入rootIndex,进行AdjustHeap的过程。不停的移除root,直到最后没数据

    以下为测试代码:其中数组的第一个索引0没有使用。。

    #include<iostream>
    
    using namespace std;
    
    void HeapAdjust(int arr[], int begIdx, int endIdx);
    void HeapBuild(int arr[], int begIdx, int endIdx);
    void HeapRebuild(int arr[], int begIdx, int endIdx);
    int const arrSize = 9;
    void main()
    {
        int arrTest[arrSize] = { 4,53,36,30,91,47,12,24,85 };//第一个参数不参与对比,因为树根节点索引为1
        HeapBuild(arrTest, 1, arrSize - 1);
        HeapRebuild(arrTest, 1, arrSize - 1);
        return;
    }
    
    #pragma region 小根堆排序
    /*
    *建堆,实际上是从叶子的父节点开始,进行从下往上的调堆过程
    */
    void HeapBuild(int arr[], int begIdx, int endIdx)
    {
        for (int i = endIdx / 2; i >= begIdx; --i)
        {
            HeapAdjust(arr, i, endIdx);
        }
    }
    /*初始堆后,移除root重建过程*/
    void HeapRebuild(int arr[], int begIdx, int endIdx)
    {
        int rootVal = arr[begIdx];
        arr[begIdx] = arr[endIdx];
        arr[endIdx] = rootVal;
    
        int offsetNum = 0;
        for (int i = begIdx; i < endIdx - offsetNum; ++i, ++offsetNum)
        {
            int lastIdx = endIdx - offsetNum-1;
            HeapAdjust(arr, begIdx, lastIdx);
            //交换数据
            int temp = arr[begIdx];
            arr[begIdx] = arr[lastIdx];
            arr[lastIdx] = temp;
        }
    }
    
    /*调堆的过程,除了根外,其他结点都是有序的*/
    void HeapAdjust(int arr[], int begIdx, int endIdx)
    {
        int rootVal = arr[begIdx];//无序的根结点
        int tempIdx = begIdx;
        //从子节点往下搜
        for (int i = 2 * begIdx; i <= endIdx; i = 2 * i)
        {
            //对比左右子树,确保小的和父节点对比
            if ((i + 1) <= endIdx&&arr[i] > arr[i + 1])
            {
                i = i + 1;
            }
            if (rootVal <= arr[i])
            {
                break;
            }
            else
            {
                arr[tempIdx] = arr[i];//数据上移动
                tempIdx = i;//坑变了
            }
        }
        arr[tempIdx] = rootVal;//最后把tempRootVal赋值给空余的坑下
    }
    #pragma endregion
    改变自己
  • 相关阅读:
    方维P2P  二次开发
    Array 数组去重 总结10方法(7)
    PHP  OOP学习总结
    [转载]js:数组里面获取键名和键值
    Array对象的方法实现(6)----Array.prototype.indexOf(实现常规参数的功能)
    在Apache服务器上启用GZip压缩静态内容的方法
    PHP 程序授权验证开发思路
    【转】zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法
    公钥私钥,HTTPS,CA证书机构,单向和双向认证
    Array对象的方法实现(5)----Array.prototype.includes(实现常规参数的功能)
  • 原文地址:https://www.cnblogs.com/sun-shadow/p/6691163.html
Copyright © 2020-2023  润新知