堆排序 (C++)

/*
 * HeapSort.h
 * 堆排序
 *  Created on: 2020年2月10日
 *      Author: LuYonglei
 */

#ifndef SRC_HEAPSORT_H_
#define SRC_HEAPSORT_H_
#include <vector>
using namespace std;

template<typename T>
void siftDown(vector<T> &arr, int index, int heapSize) {
    //下滤
    T element = arr[index]; //保存父节点的元素
    int half = heapSize / 2;
    while (index < half) {
        //index必须是叶子节点
        int childIndex = 2 * index + 1; //默认是左子节点
        T childElement = arr[childIndex]; //左子节点的元素
        int rightIndex = childIndex + 1; //右子节点下标
        //若右子节点的元素大于左子节点的元素,
        if (rightIndex < heapSize && arr[rightIndex] > childElement) {
            childElement = arr[rightIndex];
            childIndex = rightIndex;
        }
        //如果大于等于子节点,就跳出循环
        if (element >= childElement)
            break;
        //如果父节点元素小于子节点元素,用子节点元素覆盖父节点元素
        arr[index] = childElement;
        index = childIndex;
    }
    arr[index] = element;
}

//1.对序列原地建堆(heapify)
//2.
//  将0号元素与末尾元素交换位置
//  堆的size-1
//  对0号元素进行下滤(siftdown)
//  重复2中的以上操作,直至size变为1
template<typename T>
void heapSort(vector<T> &arr) {
    int heapSize = arr.size();
    //原地建堆,对所有元素进行下滤
    for (int i = heapSize / 2 - 1; i >= 0; i--)
        siftDown(arr, i, heapSize);
    while (heapSize > 1) {
        //交换堆顶元素和堆尾部元素,堆大小减小1
        swap(arr[0], arr[--heapSize]);
        //对堆顶元素进行下滤
        siftDown(arr, 0, heapSize);
    }
}

#endif /* SRC_HEAPSORT_H_ */

 

posted @ 2020-02-16 18:21  路璐  阅读(187)  评论(0编辑  收藏  举报