假定有20个有序数组,每个数组有500个数字,数字类型32位uint数值,现在需要取出这10000个数字中最大的500个,怎么做?
思路:20个有序数组,不妨设数序为降序。首先把20个数组中最大的(也就是a[i][0])进行大堆排序,输出堆顶元素(最大),在输出的那个元素之前所在的数组中,取下一个元素,放到堆顶,然后进行堆排序,在输出堆顶元素,依次循环输出500个即可。(输出最小的500,同样的道理,只不过进行小堆排序),这样充分利用了题干的条件。
- #include<iostream>
- using namespace std;
- struct node
- {
- int data;
- int next;
- };
- node obj[20];
- void sift(int k,int m,int b[])//调整一个元素在堆的位置
- {
- int i=k,j=2*i+1,temp;
- while(j<m)
- {
- if(j<m-2&&b[j]<b[j+1])// 体会j<m
- j++;
- if(b[i]>=b[j]) break;
- else {
- temp=b[i];
- b[i]=b[j];
- b[j]=temp;
- i=j;
- j=2*j+1;
- }
- }
- }
- void s_hsort(int n,int a[][500])
- {
- int temp=0,j=0;
- int b[20];
- for(int k=0;k<20;k++)
- {
- b[k]=a[k][0];
- obj[k].data=a[k][0];
- obj[k].next=1;
- }
- for(k=0;k<500;k++)
- {
- for(int i=(n-1)/2;i>=0;i--)//把20个元素调整为大堆的形式
- sift(i,n,b);
- cout<<b[0]<<endl;//输出堆顶
- for(i=0;i<20;i++)//把堆顶值换成下一个入堆的元素
- if(b[0]==obj[i].data)
- temp=i;
- b[0]=a[temp][obj[temp].next];
- obj[temp].data=b[0];
- obj[temp].next+=1;
- }
- }
- int main()
- {
- int a[20][500];
- for(int j=0;j<20;j++)//初始化这个二维数组
- for(int i=0;i<500;i++)
- a[j][i]=10000-(i+1)-50*j;
- s_hsort(20,a);
- return 0;
- }