查找大量无序元素中最大的K个数给定一个数组,用最短时间求其中最大的k个数。

题目

1.题目要求:

给定一个数组,用最短时间求其中最大的k个数。

编写函数

void FindMax(int Array[],int k,int size,int kMax[])

//k为需要查找的最大元素个数,size为数组大小,kMax存储最大的k个元素  

有一个大数组,要求找出数组的最大值、最小值。要求用最短的时间完成最大值与最小值的查找。

2.题目分析:

这里我用的是堆排序(优先队列)

因为查找出最大值只要用大根堆一个个弹出根节点就可以

代码分析:

1.向上调整堆的构造:

解析都写注释里了bushi

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

// 向上调整堆  
void heapify(int arr[], int n, int i) {//把大的放在根节点 下滤  大根堆的构造
    int smallist = i;
    int left = 2 * i + 1;//左节点
    int right = 2 * i + 2;//右节点
    //n是大小
    if (left < n && arr[left] > arr[smallist])
        smallist = left;

    if (right < n && arr[right] > arr[smallist])
        smallist = right;

    if (smallist != i) {
        //交换
        swap(&arr[i], &arr[smallist]); //与根节点交换 这时候的根节点已经与子节点交换
        heapify(arr, n, smallist); //这个时候的smallist是一个较小的节点
    }
}

关于堆的构造可以看这两个:

【从堆的定义到优先队列、堆排序】 10分钟看懂必考的数据结构——堆

数据结构 | 堆的实现 向上调整算法 向下调整算法 堆排序

ps:讲的很好怎么就这么少人点赞呢,不理解

2.查找最大数

// 查找最大的K个数  
void FindMax(int Array[], int k, int size, int kMax[]) {  
    //传入数组 ,传入需要找的最大k的个数  传入数组的大小  传入需要保存的数组
    // 构建最小堆  
    for (int i = size / 2 - 1; i >= 0; i--) //从中间开始 这时候的i需要-1 数组从零开始
        heapify(Array, size, i);//  从下面的节点开始向上构建堆结构 都是每个根节点的传入 
    //最上面的根节点i是零  

    // 提取最大的K个数  
    for (int i = 0; i < k && i < size; i++) {
        kMax[i] = Array[0];
        Array[0] = Array[size - i - 1];//把最右叶子节点作为根节点(最后一个元素)
        //比如i=0,size=7时
        /*            15                                      7                          
                     /   \                 / \               / \
                   10     13      ->     10  13     ->     10   13
                  /  \   /  \           / \  / \           / \  / 
                 4    5 6    7         4   5 6  7         4   5 6                              */
        size--;
        heapify(Array, size, 0);//每次弹出后要重新构建堆
    }
}

3.完整代码

#include <stdio.h>  
#include <stdlib.h>  

// 交换两个元素  
void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

// 向上调整堆  
void heapify(int arr[], int n, int i) {//把大的放在根节点 下滤  大根堆的构造
    int smallist = i;
    int left = 2 * i + 1;//左节点
    int right = 2 * i + 2;//右节点
    //n是大小
    if (left < n && arr[left] > arr[smallist])
        smallist = left;

    if (right < n && arr[right] > arr[smallist])
        smallist = right;

    if (smallist != i) {
        //交换
        swap(&arr[i], &arr[smallist]); //与根节点交换 这时候的根节点已经与子节点交换
        heapify(arr, n, smallist); //这个时候的smallist是一个较小的节点
    }
}

// 查找最大的K个数  
void FindMax(int Array[], int k, int size, int kMax[]) {  
    //传入数组 ,传入需要找的最大k的个数  传入数组的大小  传入需要保存的数组
    // 构建最小堆  
    for (int i = size / 2 - 1; i >= 0; i--) //从中间开始 这时候的i需要-1 数组从零开始
        heapify(Array, size, i);//  从下面的节点开始向上构建堆结构 都是每个根节点的传入 
    //最上面的根节点i是零  

    // 提取最大的K个数  
    for (int i = 0; i < k && i < size; i++) {
        kMax[i] = Array[0];
        Array[0] = Array[size - i - 1];//把最右叶子节点作为根节点(最后一个元素)
        //比如i=0,size=7时
        /*            15                                      7                          
                     /   \                 / \               / \
                   10     13      ->     10  13     ->     10   13
                  /  \   /  \           / \  / \           / \  / 
                 4    5 6    7         4   5 6  7         4   5 6                              */
        size--;
        heapify(Array, size, 0);//每次弹出后要重新构建堆
    }
}

// 测试  
int main() {
    int Array[] = { 3, 2, 1, 5, 6, 4 };
    int k = 3;
    int kMax[3];
    FindMax(Array, k, sizeof(Array) / sizeof(Array[0]), kMax);

    for (int i = 0; i < k; i++) {
        printf("%d ", kMax[i]);
    }

    return 0;
}

ps:

构建堆的时间复杂度为O(logN)

只是很简单的对于堆排序的应用,查查资料什么的包学会的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值