堆的实现
package queuedemo;
import java.util.Arrays;
public class HeapDemp {
public int[] elem;
public int usedSize;
public HeapDemp(){
this.elem = new int[10];
}
public void adjustDown( int parent ,int len){
int child = 2*parent+1;
//说明有左孩子,child +1判断是否有右孩子
while(child<len){
if( child+1<len&&this.elem[child] < this.elem[child+1]){
child++;
}
//child 下标一定是左右孩子的最大值
if(this.elem[child] > this.elem[parent]){
int tmp = this.elem[child];
this.elem[child] = this.elem[parent];
this.elem[parent] = tmp;
parent = child;
child = 2*parent+1;
}else{
break;
}
}
}
public void adjustUp(int child){
int parent = (child-1)/2;
while(child >0){
if(this.elem[child] > this.elem[parent]){
int tmp = this.elem[child];
this.elem[child] = this.elem[parent];
this.elem[parent] = tmp;
child = parent;
parent =(child -1)/2;
}else {
break;
}
}
}
public void push(int val){
if(isFull()){
this.elem=
Arrays.copyOf(this.elem,2*this.elem.length);
}
this.elem[this.usedSize] = val;
this.usedSize++;
adjustUp(this.usedSize-1);
}
/**
* 第一个和最后一个换,
* 向下调整 0下标这棵树
* @return
*/
public int poll(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
int ret = this.elem[0];
int tmp = this.elem[0];
this.elem[0] = this.elem[this.usedSize-1];
this.elem[this.usedSize-1] = tmp;
this.usedSize--;
adjustDown(0,this.usedSize);
return ret;
}
public int peek(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return this.elem[0];
}
public boolean isEmpty(){
return this.usedSize == 0;
}
public boolean isFull(){
return this.usedSize == this.elem.length;
}
public void createBigHeap( int[] array){
for(int i = 0;i<array.length;i++){
this.elem[i] = array[i];
usedSize++;
}
//elem当中已经存放了元素
for(int i = (this.usedSize-1-1)/2;i>=0;i--){
adjustDown(i,this.usedSize);
}
}
public void show(){
for (int i = 0;i<this.usedSize;i++){
System.out.print(this.elem[i] +" ");
}
System.out.println();
}
}
``
堆实现Top-k问题
问题描述
有10 个元素 k = 3 要求前 k 个最大或者最小的元素
思路:要求前k个最小的元素建大堆
要求前K个最大的元素建小堆
时间复杂度nlog2k
前 k 个最大的元素
import java.util.Comparator;
import java.util.PriorityQueue;
public class class_Topk {
public static void Topk (int[] array, int k){
// 大小为 k 的小堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 -o2;
}
});
//2,遍历数组
for (int i =0;i<array.length;i++){
if (minHeap.size() < k){
minHeap.offer(array[i]);
}else{
int top = minHeap.peek();
if (array[i] > top){
minHeap.poll();
minHeap.offer(array[i]);
}
}
}
for (int i=0; i<k; i++){
System.out.println(minHeap.poll());
}
}
public static void main(String[] args) {
int[] array = {27,15,19,18,28,34,65,49,25,37};
Topk(array,3);
}
}
运行结果
求前 K 个最小的元素只需将建堆的代码o1-o2 换成o2-o1
遍历代码中换成 array[i] < top
import java.util.Comparator;
import java.util.PriorityQueue;
public class class_Topk {
public static void Topk (int[] array, int k){
// 大小为 k 的大堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 -o1;
}
});
//2,遍历数组
for (int i =0;i<array.length;i++){
if (minHeap.size() < k){
minHeap.offer(array[i]);
}else{
int top = minHeap.peek();
if (array[i] < top){
minHeap.poll();
minHeap.offer(array[i]);
}
}
}
for (int i=0; i<k; i++){
System.out.println(minHeap.poll());
}
}
public static void main(String[] args) {
int[] array = {27,15,19,18,28,34,65,49,25,37};
Topk(array,3);
}
}
运行结果 19 18 15
堆实现第k小的问题
有10 个元素 k = n 要求前第k 大或者第k小的元素
思路:
建立大小为 k的大堆,等数组遍历完成后,堆顶元素就是第k 小的元素
代码 与上面代码相似
在import java.util.Comparator;
import java.util.PriorityQueue;
public class class_Topk {
public static void Topk (int[] array, int k){
// 大小为 k 的小堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 -o1;
}
});
//2,遍历数组
for (int i =0;i<array.length;i++){
if (minHeap.size() < k){
minHeap.offer(array[i]);
}else{
int top = minHeap.peek();
if (array[i] < top){
minHeap.poll();
minHeap.offer(array[i]);
}
}
}
System.out.println(minHeap.poll());
}
public static void main(String[] args) {
int[] array = {27,15,19,18,28,34,65,49,25,37};
Topk(array,3);
}
}