ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

数据结构与算法 - 堆排序

2022-03-01 14:34:34  阅读:121  来源: 互联网

标签:index arr 排序 int 堆排序 算法 length 数据结构 present


堆排序

顾名思义,是利用堆这种数据结构来进行排序的算法。

如果你了解堆这种数据结构,你应该知道堆是一种优先队列,两种实现,最大堆和最小堆,由于我们这里排序按升序排,所以就直接以最大堆来说吧。

我们完全可以把堆(以下全都默认为最大堆)看成一棵完全二叉树,但是位于堆顶的元素总是整棵树的最大值,每个子节点的值都比父节点小,由于堆要时刻保持这样的规则特性,所以一旦堆里面的数据发生变化,我们必须对堆重新进行一次构建。

既然堆顶元素永远都是整棵树中的最大值,那么我们将数据构建成堆后,只需要从堆顶取元素不就好了吗? 第一次取的元素,是否取的就是最大值?取完后把堆重新构建一下,然后再取堆顶的元素,是否取的就是第二大的值? 反复的取,取出来的数据也就是有序的数据。

image

我们以[ 8,2,5,9,7,3 ]这组数据来演示。

首先,将数组构建成堆。

image

既然构建成堆结构了,那么接下来,我们取出堆顶的数据,也就是数组第一个数 9 ,取法是将数组的第一位和最后一位调换,然后将数组的待排序范围 -1。

image

现在的待排序数据是[ 3,8,5,2,7 ],我们继续将待排序数据构建成堆。

image

取出堆顶数据,这次就是第一位和倒数第二位交换了,因为待排序的边界已经减 1 。

image

继续构建堆

image

从堆顶取出来的数据最终形成一个有序列表,重复的步骤就不再赘述了,我们来看一下代码实现。

代码实现

void sort(vector<int>& arr)
{
    int length = arr.size();
    buildHeap(arr, length);
}

void buildHeap(vector<int>& arr, int length)
{
    for(int i = length/2; i >=0; i--) {
        sink(arr, i, length);
    }
}

// 下沉调整
void sink(vector<int>& arr,int index, int length)
{
    int leftChild = 2 * index +1; // 左孩子下标
    int rightChild = 2 * index + 2; // 右孩子下标
    int present = index;    // 要调整的节点下标

    // 下沉左边
    if(leftChild < length && arr[leftChild] > arr[present]) {
        present = leftChild;
    }

    // 下沉右边
    if(rightChild < length && arr[rightChild] > arr[present]) {
        present = rightChild;
    }

    // 如果下标不想等 证明调换过了
    if (present != index)
    {
        // 交换值
        int temp = arr[index];
        arr[index] = arr[present];
        arr[present] = temp;

        // 继续下沉
        sink(arr, present, length);
    }

}

标签:index,arr,排序,int,堆排序,算法,length,数据结构,present
来源: https://www.cnblogs.com/loganxu/p/15950019.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有