考研数据结构笔记—堆排序

 

完全二叉树是效率很高的数据结构,堆是一种完全二叉树或者近似完全二叉树,所以效率同样极高。目前十分常用的排序算法、Dijkstra算法、Prim算法等都要用堆才能优化。

堆排序是一种选择排序算法,与原序列的初始排列次序无关,即最好、最坏和一般情况排序的时间复杂度不变,均为O(nlgn)。而且,堆排序只需要一个记录元素大小的辅助空间(供交换使用),故空间复杂度为O(1)。正由于堆排序不仅时间复杂度小,而且空间复杂度O(1)也是最小,所以是用于排序的最佳选择。

堆的定义 

n个元素序列 { k0,k1,..., k} 当且仅当满足下列条件之一时,称之为堆(其中 i = 0, 1, ..., n/2 向下取整)。

  • ki <= k2i+1 且 k<= k2i+2(最小堆)
  • ki >= k2i+1 且 ki >= k2i+2(最大堆)

堆排序实现  

利用最大堆性质实现堆排序

#include <iostream>
using namespace std;

/*交换数组中两个元素的值*/
void Swap(int *arr, int a, int b)
{
    int temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
}

/*(大根)堆调整*/
void maxHeapify(int *arr, int length, int curNode)
{
    /*找出当前节点和其左右节点三者的最大值*/
    int maxNode = curNode;
    int left = curNode * 2 + 1;
    int right = curNode * 2 + 2;
    if (left < length && arr[left] > arr[maxNode]) //左孩子存在且较大
        maxNode = left;
    if (right < length && arr[right] > arr[maxNode]) //右孩子存在且较大
        maxNode = right;

    if (maxNode != curNode)    //当前节点不是最大则需要交换
    {
        Swap(arr, maxNode, curNode);
        maxHeapify(arr, length, maxNode);  //子节点需重新调整
    }
}

/*(最大)堆排序
*思想:
*1、构建最大堆
*2、从最后一个元素开始只第二个元素将依次与首元素交换
*3、进行数组中当前元素前面的所有元素的局部调整堆
*上面步骤2和步骤3将所有元素都与首元素交换,将局部范围内的最大值沉到后面,然后进行当前元素前面所有元素的局部范围内的堆调整
*即在数组A中,当前元素索引为i,将A[i]与A[0]交换,将A[0,1,...,i]中最大的值放到A[i],然后进行A[0,1,...,i-1]堆调整,
*将A[0,1,...,i-1]内的最大值放到A[0]中,待下一次交换使用,实现将局部的最大值依次沉到数组后面,完成排序
*/
void heapSort(int *arr, int length)
{
     //构建堆
    for (int i = length / 2 - 1; i >= 0; i--)  //从最后一个非叶节点开始
    {
        maxHeapify(arr, length, i);
    }

    for (int i = length - 1; i > 0; i--)
    {
        Swap(arr, 0, i);  //与首元素交换
        maxHeapify(arr, i, 0);  //调整堆
    }
}

int main()
{
    cout << "堆排序算法实现" << endl;
    int data[] = { 6,8,2,3,9,7,4,1,5,10 };
    cout << "排序之前的数据:";
    for (int i = 0; i<10; i++)
        cout << data[i] << " ";
    cout << endl;
    heapSort(data, 10);
    cout << "排序之后的数据:";
    for (int i = 0; i<10; i++)
        cout << data[i] << " ";
    cout << endl;
    system("pause");
    return 0;
}

 

转载于:https://www.cnblogs.com/evenleee/p/8529169.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值