package org.jyjiao;
class HeapItem{
private int arrayIndex;
private int data;
private int curIndex;
public HeapItem(int arrayIndex,int data){
this.arrayIndex=arrayIndex;
this.data=data;
}
public int getArrayIndex(){
return this.arrayIndex;
}
public int getData(){
return this.data;
}
public void setArrayIndex(int index){
this.arrayIndex=index;
}
public void setData(int data){
this.data=data;
}
public int getCurIndex() {
return curIndex;
}
public void setCurIndex(int curIndex) {
this.curIndex = curIndex;
}
}
class Heap{
int count=0;
HeapItem[] items;
int[] arrayCurIndex;
//建立规模为m的堆数组,m为顺序数组的个数
public Heap(int m){
items=new HeapItem[m];
arrayCurIndex=new int[m];
}
//删除堆顶元素
public HeapItem delTop(){
arrayCurIndex[items[0].getArrayIndex()]+=1;
return items[0];
}
//获得某个数组下一个要出队的元素下标
public int getCurIndex(int arrayIndex){
return arrayCurIndex[arrayIndex];
}
public HeapItem getNextItem(int i){
return items[i+1];
}
//利用所有数组的第一个元素建堆
public void createHeap(int[] firArray){
for(int i=0;i<firArray.length;i++){
items[i]=new HeapItem(i,firArray[i]); //注意这里:对象数组的元素使用之前必须new该元素
}
for(int i=firArray.length/2-1;i>=0;i--){
siftDown(i);
}
}
/*向上筛
void siftUp(int i){
}
*/
//建堆后插入一个新元素到堆顶
public void insert(int i,int data){
HeapItem item=new HeapItem(i,data);
int ret=items[0].getArrayIndex();
items[0]=item;
siftDown(0);
}
//向下筛
void siftDown(int i){
int j=2*i+1;
if(items.length>1){
HeapItem tmp=items[i];
while(j<items.length){
if((j<(items.length-1))&&(items[j].getData()<items[j+1].getData())){
j++;
}
if(items[j].getData()>tmp.getData()){
items[i]=items[j];
i=j;
j=2*j+1;
}else{
break;
}
}
items[i]=tmp;
}
}
}
public class MutiMaxK {
public void getMaxK(int[][] array,int K){
int m=array.length;
HeapItem[] retArray=new HeapItem[K];
int count=0;
/*算法步骤:
* 1. 对每个有序数组的首元素建最大堆,最大堆的元素为【data,arrayIndex】
* 2. 将堆顶元素放入结果数组中,如果该数组的个数==K个,则停止;否则,取出堆顶元素所在的数组中的下一个元素放在堆顶,然后siftdown
* 3. 打印结果
*/
//创建初始堆
Heap heap=new Heap(m);
int[] firArray=new int[m];
for(int i=0;i<m;i++){
firArray[i]=array[i][0];
}
heap.createHeap(firArray);
HeapItem[] MaxK=new HeapItem[K];
//取出下一元素放入堆中
while(count<K){
MaxK[count]=heap.delTop();
int nextIndex=MaxK[count].getArrayIndex();
int curIndex=heap.getCurIndex(nextIndex);
int top=0;
while(curIndex>(array[nextIndex].length-1)){
HeapItem hitem=heap.getNextItem(top);
nextIndex=hitem.getArrayIndex();
curIndex=heap.getCurIndex(nextIndex);
top=top+1;
}
int data=array[nextIndex][curIndex];
heap.insert(nextIndex, data);
count++;
}
//打印结果
for(int j=0;j<K;j++){
System.out.println("第"+(j+1)+"大="+MaxK[j].getData()+" 来自第"+MaxK[j].getArrayIndex()+"队列");
}
}
public static void main(String[] args){
int[][]array={{9,7,5,3,1},{10,8,6,4,2},{11,9,7,5,3},{19,12,11,10,8,6},{20,9,7,5,2,1}};
MutiMaxK m=new MutiMaxK();
m.getMaxK(array,2);
}
}