C语言笔试:top K 问题

经过几次C语言笔试,发现经常会被问到求1万个数中前100大的数,现在想了两种方法来解决:

方法一:一维数值

代码如下:

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

//求数组的最大值,返回b【0】
int max(int b[],int n)
{
 int i,t,k=0,m=0;
 int c=n;
 //将数组两两进行比较,把较大值至于最前面
  while(n!=1)
  {   
    for(i=0;i<n;i++)
    {
    if(b[i]>b[i+1])
    {
      t=0;
    t=b[i];
    b[i]=b[i/2];
     b[i/2]=t;
       }
     else{
        t=0;
     t=b[i+1];
       b[i+1]=b[i/2];
     b[i/2]=t; 
     }
     i++;
      }
      n=n/2;
  }
  m=b[0];
  return m;
}
int main(int argc, char *argv[])
{
 int *test,i,k,d=0,x=0,y=0;
 int l=100000,h=100;     //l表示数的总个数,h表示要求的前h大数
 int m[h];
 d=l;
 if(d&(d-1))
 {
   while(d>1){
    d>>=1;
        x++;}
  x++;  
 }
 else
 {
  while(d>1){
    d>>=1;
        x++;}         //x表示要进行的比较次数,y表示要申请的空间大小
 }
 y=pow(2,x);
 srand(time(0));
    test=(int *)malloc(sizeof(int)*y);  
    for(long a=0;a<l;a++)
    {
    test[a]=rand()%100000+1;   //动态生成随机数
    printf("%d ",test[a]);
    }
    printf("\n");
    for(i=l;i<y;i++)
    {
     test[i]=0;
    }
    m[0]=max(test,y);
    for(i=1;i<h;i++)
    {
   for(k=0;k<l;k++)
      {
         if(test[k]==m[i-1])
   test[k]=0;
      }
      m[i]=max(test,y);
    }
    printf("这%d个数中前%d大的数分别为:\n",l,h);
    for(i=0;i<h;i++)
 {
  printf("%d ",m[i]);
 }
 printf("\n");
 printf("单次比较次数为:%d\n",x);
 printf("总计比较次数为:%d\n",h*x);
 printf("\n");
 free(test);
 test=NULL;
 return 0;
 }

方法二:哈夫曼树

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int ElemType; 
struct BTreeNode 

    ElemType data; 
    struct BTreeNode* left; 
    struct BTreeNode* right; 
}; 
//根据数组 a 中 n 个权值建立一棵哈夫曼树,返回树根指针 
struct BTreeNode* CreateHuffman(ElemType a[], int n) 

    int i, j;
    struct BTreeNode **b, *q; 
    b = (BTreeNode **)malloc(sizeof(struct BTreeNode)*n);
    for (i = 0; i < n; i++) //初始化b指针数组,使每个指针元素指向a数组中对应的元素结点 
    { 
        b[i] = (BTreeNode *)malloc(sizeof(struct BTreeNode)); 
        b[i]->data = a[i]; 
        b[i]->left = b[i]->right = NULL; 
    } 
    for (i = 1; i < n; i++)//进行 n-1 次循环建立哈夫曼树 
    { 
        //k1表示森林中具有最小权值的树根结点的下标,k2为次最小的下标 
        int k1 = -1, k2; 
        for (j = 0; j < n; j++)//让k1初始指向森林中第一棵树,k2指向第二棵 
        { 
            if (b[j] != NULL && k1 == -1) 
            { 
                k1 = j; 
                continue; 
            } 
            if (b[j] != NULL) 
            { 
                k2 = j; 
                break; 
            } 
        } 
        for (j = k2; j < n; j++)//从当前森林中求出最小权值树和次最小 
        { 
            if (b[j] != NULL) 
            { 
                if (b[j]->data < b[k1]->data) 
                { 
                    k2 = k1; 
                    k1 = j; 
                } 
                else if (b[j]->data < b[k2]->data) 
                    k2 = j; 
            } 
        } 
        //由最小权值树和次最小权值树建立一棵新树,q指向树根结点 
        q = (BTreeNode *)malloc(sizeof(struct BTreeNode)); 
        q->data = b[k2]->data; 
        q->left = b[k1]; 
        q->right = b[k2]; 
 
        b[k1] = q;//将指向新树的指针赋给b指针数组中k1位置 
        b[k2] = NULL;//k2位置为空 
    } 
    free(b); //删除动态建立的数组b 
    return q; //返回整个哈夫曼树的树根指针 

int main(int argc, char *argv[])
{
 int *test;
 int l=100,h=10,i,k;
 int m[h];
 struct BTreeNode* q;
 srand(time(0));
    test=(int *)malloc(sizeof(int)*l);
    for(long a=0;a<l;a++)
    {
    test[a]=rand()%100+1;
    printf("%d ",test[a]);
    }
    printf("\n");
    q=CreateHuffman(test,l);
    m[0]=q->data;
    for(i=1;i<h;i++)
    {
   for(k=0;k<l;k++)
      {
         if(test[k]==m[i-1])
   test[k]=0;
      }
      q=CreateHuffman(test,l);
      m[i]=q->data;
    }
    printf("这%d个数中前%d大的数分别为:\n",l,h);
    for(i=0;i<h;i++)
 {
  printf("%d ",m[i]);
 }
 printf("\n");
 printf("比较次数为:%d",l-1);
 printf("\n");
 return 0;
}

运行结果如下:

时间: 2024-10-05 16:10:54

C语言笔试:top K 问题的相关文章

Top k问题的讨论(三种方法的java实现及适用范围)

在很多的笔试和面试中,喜欢考察Top K.下面从自身的经验给出三种实现方式及实用范围. 合并法 这种方法适用于几个数组有序的情况,来求Top k.时间复杂度为O(k*m).(m:为数组的个数).具体实现如下: /** * 已知几个递减有序的m个数组,求这几个数据前k大的数 *适合采用Merge的方法,时间复杂度(O(k*m); */ import java.util.List; import java.util.Arrays; import java.util.ArrayList; public

Top k问题(线性时间选择算法)

问题描述:给定n个整数,求其中第k小的数. 分析:显然,对所有的数据进行排序,即很容易找到第k小的数.但是排序的时间复杂度较高,很难达到线性时间,哈希排序可以实现,但是需要另外的辅助空间. 这里我提供了一种方法,可以在O(n)线性时间内解决Top k问题.关于时间复杂度的证明,不再解释,读者可以查阅相关资料.具体的算法描述如下: 算法:LinearSelect(S,k) 输入:数组S[1:n]和正整数k,其中1<=k<=n: 输出:S中第k小的元素 1. If  n<20  Then  

排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结束.时间复杂度:O(n^2) 选择排序:每次在无序队列中"选择"出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别).时间复杂度:O(n^2) 直接插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插

Top k 问题

Top K的问题: 给出大量数据,找出其中前K个最大(小)的数,或者在海量数据中找到出现频率最好的前K个数. 一.给出大量数据(N个),找出其中前K个最大数(没有其他资源上的限制) 1.使用排序算法 直接使用排序算法,如快速排序,然后遍历找到最大的K个数.时间复杂度为O(NlogN): 2.部分排序 因为,只要求出前K个最大值,所以我们不必全部排好.思路是:随意选出K个数形成一个数组,然后按从大到小进行排序,再从剩下的数中,选取一个数和数组中的最小值进行比较,若小于最小值,则取下一个数继续比较:

347. Top K Frequent Elements

Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2,2,3] and k = 2, return [1,2]. Note: 347. Top K Frequent ElementsYou may assume k is always valid, 1 ≤ k ≤ number of unique elements. Your algorithm's

Top K Frequent Words

Given a list of words and an integer k, return the top k frequent words in the list. Given [ "yes", "lint", "code", "yes", "code", "baby", "you", "baby", "chrome", &

Spark 编程实战之经典算法TOP K

Top K Top K算法有两步,一是统计词频,二是找出词频最高的前K个词. 1.实例描述 假设取Top 1,则有如下输入和输出. 输入: Hello World Bye World Hello Hadoop Bye Hadoop Bye Hadoop Hello Hadoop 输出: 词Hadoop 词频4 2.设计思路 首先统计WordCount的词频,将数据转化为(词,词频)的数据对,第二个阶段采用分 治的思想,求出RDD每个分区的Top K,最后将每个分区的Top K结果合并以产生新的集

Top K问题!!!!!!!!!!!!!

转:http://blog.csdn.net/boo12355/article/details/11788655 Top K 算法详解应用场景: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节.        假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个.一个查询串的重复度越高,说明查询它的用户越多,也就是越热门.),请你统计最热门的10个查询串,要求使用的内存不能超过1G. 必备知识:什么

Top K and Quick Selection

The common solutions for top k problem are heap (priority queue) and quick selection. Using heap is very straight-forward, while quick selection with partition is more complicated and I didnot find any satisfying code online, so document as following