合并多个有序数组

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);
	}
	
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值