目录



//建立大根堆,每一棵子树的调整属于向下调整
public void createHeap(){
for (int parent = (usedSize-1-1)/2; parent >= 0 ; parent--) {
shiftDown(parent,usedSize);
}
}
//向下调整
public void shiftDown(int parent,int len){
int child = parent*2 + 1;
//parent和child只是下标
while(parent < len){
if(child+1 < len && elem[child] < elem[child+1]){
child++;
}
if(elem[child] > elem[parent]){
int tmp = elem[child];
elem[child] = elem[parent];
elem[parent] = tmp;
parent = child;
child = 2*parent + 1;
}
else{
break;
}
}
}




//入堆,需要向上调整
public void offer(int x){
if(isFull()){
elem = Arrays.copyOf(elem,elem.length*2);
}
this.elem[usedSize] = x;
usedSize++;
shiftUp(usedSize-1);
}
private boolean isFull() {
return usedSize == elem.length;
}
//向上调整
public void shiftUp(int child){
int parent = (child-1)/2;
while(child > 0){
if(elem[child] > elem[parent]){
int tmp = elem[child];
elem[child] = elem[parent];
elem[parent] = tmp;
child = parent;
parent = (child-1)/2;
}else{
break;
}
}
} //出堆,需要向下调整
public int poll(){
if(isEmpty()){
return -1;
}
int oldvalue = elem[0];
int tmp = elem[0];
elem[0] = elem[usedSize-1];
elem[usedSize-1] = tmp;
usedSize--;
shiftDown(0,usedSize);
return oldvalue;
}
private boolean isEmpty(){
return usedSize == 0;
} - class TestHeap{
- public int[] elem;
- public int usedSize;
-
- public TestHeap() {
- this.elem = new int[10];
- this.usedSize = usedSize;
- }
-
- public void initArray(int[] array){
- elem = Arrays.copyOf(array,array.length*2);
- usedSize = elem.length;
- }
- //建立大根堆
- public void createHeap(){
- for (int parent = (usedSize-1-1)/2; parent >= 0 ; parent--) {
- shiftDown(parent,usedSize);
- }
- }
- //向下调整
- public void shiftDown(int parent,int len){
- int child = parent*2 + 1;
-
- while(parent < len){
- if(child+1 < len && elem[child] < elem[child+1]){
- child++;
- }
- if(elem[child] > elem[parent]){
- int tmp = elem[child];
- elem[child] = elem[parent];
- elem[parent] = tmp;
- parent = child;
- child = 2*parent + 1;
- }
- else{
- break;
- }
- }
- }
-
- //入堆,需要向上调整
- public void offer(int x){
- if(isFull()){
- elem = Arrays.copyOf(elem,elem.length*2);
- }
- this.elem[usedSize] = x;
- usedSize++;
- shiftUp(usedSize-1);
-
-
- }
-
- private boolean isFull() {
- return usedSize == elem.length;
- }
-
- //向上调整
- public void shiftUp(int child){
- int parent = (child-1)/2;
- while(child > 0){
- if(elem[child] > elem[parent]){
- int tmp = elem[child];
- elem[child] = elem[parent];
- elem[parent] = tmp;
- child = parent;
- parent = (child-1)/2;
- }else{
- break;
- }
- }
- }
-
- //出堆,需要向下调整
- public int poll(){
- if(isEmpty()){
- return -1;
- }
- int oldvalue = elem[0];
- int tmp = elem[0];
- elem[0] = elem[usedSize-1];
- elem[usedSize-1] = tmp;
- usedSize--;
- shiftDown(0,usedSize);
- return oldvalue;
- }
- private boolean isEmpty(){
- return usedSize == 0;
- }
- }
-
- public class Main {
- public static void main(String[] args) {
- int[] elem = { 27,15,19,18,28,34,65,49,25,37 };
- TestHeap testHeap = new TestHeap();
- testHeap.initArray(elem);
- testHeap.createHeap();
- System.out.println("调试!");
- }
- }
//方法1 class IntCmp implements Comparator{ @Override public int compare(Integer o1, Integer o2) { //小根堆 return o1 - o2; //大根堆 return o2 - o1; } } public static void main(String[] args) { PriorityQueue priorityQueue = new PriorityQueue<>(new IntCmp()); } //方法2 PriorityQueue priorityQueue = new PriorityQueue<>(new Comparator () { @Override public int compare(Integer o1, Integer o2) { //大根堆 return o2 - o1; } });
top-K问题: 1.求前k个最大的,建大小为k的小堆。拿剩下的元素和堆顶元素比较,剩下元素大于堆顶,则删除堆顶元素,入大的元素。 2.求前k个最小的,建大小为k的大堆。拿剩下的元素和堆顶元素比较,剩下元素小于堆顶,则删除堆顶元素,入小的元素。 3.求第k个最大的,建大小为k的小堆,堆顶元素就是第k个最大的。拿剩下的元素和堆顶元素比较,剩下元素大于堆顶,则删除堆顶元素,入大的元素。 4.求第k个最小的,建大小为k的大堆,堆顶元素就是第k个最小的。拿剩下的元素和堆顶元素比较,剩下元素小于堆顶,则删除堆顶元素,入小的元素。
堆排序,若将一组数据从小到大排序,要求在原数组上进行调整,不得创建新的数组。解题思路:建立大根堆;将堆顶元素也就是最大值和最后一个下标元素交换;交换后向下调整再让end--即可。此处留心shiftDown(array, 0, end); 后再 end--;
top-k问题的代码实现:
- public int[] smallestK(int[] array,int k){
- int[] ret = new int[k];
- if(k == 0) return ret;
-
- PriorityQueue
priorityQueue = new PriorityQueue<>(k, new Comparator() { - @Override
- public int compare(Integer o1, Integer o2) {
- return o2 - o1;
- }
- });
- for (int i = 0; i < array.length; i++) {
- if(priorityQueue.size() < k){
- priorityQueue.offer(array[i]);
- }else{
- int top = priorityQueue.peek();
- if(array[i] < top){
- priorityQueue.poll();
- priorityQueue.offer(array[i]);
- }
- }
- }
- for (int i = 0; i < k; i++) {
- ret[i] = priorityQueue.poll();
- }
- return ret;
- }
堆排序的代码实现:
- //堆排序
- public void shiftDown(int parent,int len){
- int child = 2*parent + 1;
-
- while(child
- if(child+1 < len && elem[child] < elem[child+1]){
- child++;
- }
- if(elem[child] > elem[parent]){
- int tmp = elem[child];
- elem[child] = elem[parent];
- elem[parent] = tmp;
- parent = child;
- child = 2*parent + 1;
- }else{
- break;
- }
- }
- }
- //建立一个大根堆
- public void createHeap(){
- for (int parent = (usedSize-1-1)/2; parent >= 0; parent--) {
- shiftDown(parent,usedSize);
- }
- }
- //实现堆排序
- public void heapSort() {
-
- int end = usedSize - 1;
- while (end > 0) {
- swap(array, 0, end);
- shiftDown(array, 0, end);
- end--;
- }
- }
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹