Java实现大顶堆和小顶堆
实现数据结构采用java的优先队列,通过自定义排序方式来实现不同的堆
//重写Comparator方法
//通过返回y - x和x - y来返回大顶堆和小顶堆
Comparator<Integer> cmp = new Comparator<Integer>(){
public int compare(Integer x,Integer y){
//返回大顶堆
return y - x;
//返回小顶堆
return x - y;
}
}
输出数据流中的中位数,A为小顶堆,B为大顶堆,存放的时候,如果为偶数先向A中存放,且A中存放的是较大的一半数,因此返回A.peek()正好是中位数。B中存放较小的一部分,然而为大顶堆因此返回B.peek()时返回的也刚好是右半部分中位数。
class MedianFinder {
Queue<Integer> A,B;
/** initialize your data structure here. */
public MedianFinder() {
//小顶堆
A = new PriorityQueue<>();
//大顶堆
//B = new PriorityQueue<>((x,y)->(y-x));
B = new PriorityQueue<>(new Comparator<Integer>(){
@Override
public int compare(Integer o1,Integer o2){
return o2 - o1;
}
});
}
public void addNum(int num) {
if(A.size()==B.size()){
//如果N为偶数,向A中插入数据,先放入B中再向A插入 保证较大的放入A中
B.add(num);
A.add(B.poll());
}else{
A.add(num);
B.add(A.poll());
}
}
public double findMedian() {
return A.size()!=B.size()?A.peek():((A.peek()+B.peek())/2.0);
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
quickSort(arr,0,arr.length-1);
return Arrays.copyOf(arr,k);
}
void quickSort(int[] arr,int left,int right){
if(left >= right){return;}
int i = left,j = right;
int pivot = arr[left];
while(i < j){
//快速排序先进行j--操作 再找i的位置
while(i < j&&arr[j] >= arr[left])j--;
while(i < j&&arr[i] <= arr[left])i++;
if(i < j){
//找到交换的数值 三元交换法则进行两个数值之间的交换
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
//将当前寻找到的数改为哨兵的值 将left的值改为i的值 并且对i的值进行更新操作
arr[left] = arr[i];
arr[i] = pivot;
quickSort(arr,left,i-1);
quickSort(arr,i+1,right);
}
}