30 最小的K个数

描述:

红黑树什么的俺也不懂,干脆搞个大根堆来玩玩。。。。。。。。

实现代码:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.sound.sampled.LineListener;

public class question30 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        int  k=4;
		int arr[]={4,5,1,6,2,7,3,8};
		int arr1[]={4,5,1,6,2,7,3,8};
        int arr2[]={4,5,1,6,2,7,3,8};
		getLeastNumbers(arr1,arr1.length,k);     //此方法为方法二
	ArrayList<Integer> list=	bubble(arr2,arr2.length,k);              // 此方法为方法三
		int kMaxHeap[]=new int[k];
		for (int i = 0; i < k; i++) {
			kMaxHeap[i]=arr[i];
		}
		
		// 建立大根堆,大根堆的元素个数为k
		for(int i=kMaxHeap.length/2-1;i>=0;--i)  
	        HeapAdjust(kMaxHeap,i,kMaxHeap.length);  
		
		// 依次跟大根堆的最大值比较,如果比最大值小,取而代之并且调整大根堆
		for (int i = k; i < arr.length; i++) {
			if (arr[i]<kMaxHeap[0]) {
				kMaxHeap[0]=arr[i];
				HeapAdjust(kMaxHeap, 0, k);
			}
		}
		Arrays.sort(kMaxHeap);
		System.out.println("以下是方法一的结果:");
		for (int i : kMaxHeap) {
			System.out.print(i+" ");
		}
		
		System.out.println();
		System.out.println("以下是方法二的结果:");
		for (int i = 0; i <k; i++) {
			System.out.print(arr1[i]+" ");
		}
		System.out.println();
		System.out.println("以下是方法三的结果:");
		System.out.println(list);
		
	}
	
	private static ArrayList<Integer> bubble(int[] arr, int length, int k) {
		// TODO Auto-generated method stub
		for (int i = 0; i < k; i++) {
			for (int j = 0; j < arr.length-1-i; j++) {
				if (arr[j]<arr[j+1]) {
					int t=arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=t;
				}
			}
		}
		ArrayList<Integer>  list=new ArrayList<Integer>();
		for (int i = arr.length-1; i>=arr.length-k; i--) {
			list.add(arr[i]);
		}
		return list;
	}

	// 方法二   利用分治法
	private static void getLeastNumbers(int[] arr, int length, int k) {
		// TODO Auto-generated method stub
		if (arr==null||arr.length==0||k<=0||k>length) {
			return;
		}
		int start=0;
		int end=length-1;
		int index=partition(arr,start,end);
		while (index!=k) {
			if (index>k) {
				end=index-1;
				index=partition(arr,start,end);
			}else {
				start=index+1;
				index=partition(arr,start,end);
			}
		}
		
		
	}


	private static int partition(int[] numbers, int left, int right) {
		// TODO Auto-generated method stub

		// TODO Auto-generated method stub
		int i=left;
		int j=right;
		int key=numbers[left];
		
		while (i<j) {
			while (i<j&&numbers[j]>=key)  j--;
			numbers[i]=numbers[j];
			while (i<j&&numbers[i]<=key)  i++;
			numbers[j]=numbers[i];
		}
		numbers[i]=key;
		return i;
	
	}

	//array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度
	//本函数功能是:根据数组array构建大根堆
	private static void HeapAdjust(int[] array, int i, int nLength) {  
        // TODO Auto-generated method stub  
        int nChild;  
        int nTemp;  
        for(;2*i+1<nLength;i=nChild)  
        {  
            //子结点的位置=2*(父结点位置)+1  
            nChild=2*i+1;  
            //得到子结点中较大的结点  
            if(nChild<nLength-1&&array[nChild+1]>array[nChild])++nChild;  
            //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点  
            if(array[i]<array[nChild])  
            {  
                nTemp=array[i];  
                array[i]=array[nChild];  
                array[nChild]=nTemp;   
            }  
            else break; //否则退出循环  
        }  
    }  
}

测试结果:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值