Interview question: Use heap sort to find the top-k largest number from n numbers

Sort with heap (min heap): top-k largest number


Title: top-k algorithm, from an array of size n, find the k largest numbers and output

Input: array size n=10; value of k is 5; array is: 9,8,3,2,10,20,13,1,5

Output: 20,13,10,9,8

Ideas: 1. Maintain k min heaps. If a new incoming number is greater than the root node of the min heap, then replace the root node with the new incoming number, and then adjust the min heap.
2. After finding k large numbers, perform a heap sort on the k large numbers. Because we are doing the minimum heap, the sequence obtained after heap sorting is the ascending sequence
Ps: the average time of heap sorting is complex The degree is O(n*logn), which is better than the quick sort, which is in the worst case (the array is sorted) and the time complexity is O(n^2)

/*
题目:堆排序的用法:
      1、利用堆排序从n个数字中取出top-k个最大的数字
      2、主要使用最小堆,维护k个大小的最小堆
*/
#include<iostream>
#include<vector>
using namespace std;

void headAdjust(vector<int> &arr, int start, int end){
    int temp = arr[start];
    //i这里指向的是左子树
    int i = start * 2 + 1;
    while (i <= end){
        //先找左右子树中最小的
        if (i + 1 <= end&&arr[i] > arr[i + 1]){
            //如果左子树大于右子树,则i指向右子树
            i++;
        }
        if (temp > arr[i]){
            arr[start] = arr[i];
            start = i;
            i = 2 * start + 1;
        }
        else{
            break;
        }
    }
    arr[start] = temp;
}

void heapSort(vector<int> &arr, int start, int end){
    //堆排序是从第一个非叶节点开始从下往上更新,直到更新到根节点为止
    for (int i = end / 2 - 1; i >= 0; i--){
        headAdjust(arr,i,end);
    }
    //下面进行堆排序
    for (int i = end; i-1 >= 0; i--){
        int temp = arr[i];
        arr[i] = arr[0];
        arr[0] = temp;
        headAdjust(arr, 0, i-1);
    }
}

int main(){
    //堆排序维护k个大小的最小堆
    int k;
    int n;
    cin >> n;
    cout << "top-k的值为:";
    cin >> k;
    cout << "依次输入数组,然后找出top-" << k << "个值" << endl;
    vector<int> arr(k,0);
    for (int i = 0; i < n; i++){
        if (i > k - 1){
            int temp;
            cin >> temp;
            if (temp > arr[0]){
                arr[0] = temp;
                headAdjust(arr, 0, k - 1);
            }
        }
        else{
            int temp;
            cin >> temp;
            arr[i] = temp;
            if (i == k - 1){
                headAdjust(arr, 0, k - 1);
            }
        }
    }
    //对堆进行最小堆排序
    heapSort(arr, 0, k - 1);
    for (int i = 0; i < arr.size(); i++){
        cout << arr[i];
        if (i < arr.size()-1){
            cout << " ";
        }
    }
    system("pause");
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325502526&siteId=291194637