找出N個數中最小的K個數(最小時間空間複雜度)

public class HeapFindMinK {
	private int[] r;
	private int k;
	HeapFindMinK(int[] r,int k){
		this.r = r;
		this.k = k;
	}
	
	public void findMinK(){
		int[] s = new int[k];
		for(int i = 0; i < k; i++){
			s[i] = r[i];
		}
		buildMaxHeap(s);
		for(int i = k; i < r.length;i++){
			if(r[i] < s[0]){
				s[0] = r[i];
				maxHeapify(s, k, 0);
			}
		}
	
		heapSort(s);
		for(int i = 0; i < k; i++){
			System.out.print(s[i]);
		}
	}
	
	public void swap(int[] r,int one,int two){
		int t = r[one];
		r[one] = r[two];
		r[two] = t;
	}
	
	public void printAll(){
		for(int i = 0; i < r.length;i++){
			System.out.print(r[i]);
		}
		System.out.println();
	}
	
	public void maxHeapify(int[] r,int curSize,int index){
		int left = 2*index+1;
		int right = 2*index+2;
		int larger = index;
		if(left<curSize&&r[larger] < r[left]) larger = left;
		if(right<curSize&&r[larger] < r[right]) larger = right;
		if(larger!=index){
			swap(r,larger, index);
			maxHeapify(r,curSize, larger);
		}
	}
	
	public void buildMaxHeap(int[] r){
		int count = r.length;//後面的元素其實都不需要建堆,因爲他們都沒有三個元素不會執行
		for(int i = count/2; i >= 0; i--){
			maxHeapify(r,count, i);
		}
	}
	
	public void heapSort(int[] r){
		int heapSize = r.length;
		buildMaxHeap(r);
		for(int i = r.length-1;i>0;i--){
			swap(r, i, 0);
			heapSize--;
			maxHeapify(r,heapSize,0);
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] r = {1,4,3,2,6,5,8,7,9,0};
		HeapFindMinK h = new HeapFindMinK(r,4);
		h.printAll();
		h.findMinK();
	}
}
各種排序算法都會要開闢N個空間來接收輸入,而以上代碼的方法只開闢了K的大小的空間,不斷的建堆,因爲堆的數據結構可以可以O(1)直接找到最小值,所以不用每次都比較。由於寫好了buildMaxHeap()和MaxHeapify()兩個函數,其實堆排序也就很簡單了,爲了使輸出的數組是有序的,加入了heapSort(),Okay,結束!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章