import java.util.Arrays;
import javax.management.RuntimeErrorException;
public class MyHeap {
public static void main(String args) {
MyHeap minHeap = new MyHeap(10, true);
minHeap.insert(70);
minHeap.insert(20);
minHeap.insert(90);
minHeap.insert(60);
minHeap.insert(40);
minHeap.insert(10);
minHeap.insert(50);
minHeap.insert(30);
minHeap.insert(80);
minHeap.insert(100);
System.out.println("Min Heap: " + Arrays.toString(minHeap.heap));
MyHeap maxHeap = new MyHeap(10, false);
maxHeap.insert(70);
maxHeap.insert(20);
maxHeap.insert(90);
maxHeap.insert(60);
maxHeap.insert(40);
maxHeap.insert(10);
maxHeap.insert(50);
maxHeap.insert(30);
maxHeap.insert(80);
maxHeap.insert(100);
System.out.println("Max Heap: " + Arrays.toString(maxHeap.heap));
}
private int[] heap;
private int size = 0;
private int capacity;
private boolean reverse;// true if min heap
public MyHeap(int capacity) {
this.capacity = capacity;
heap = new int[capacity];
// max heap by default
this.reverse = false;
}
public MyHeap(int capacity, boolean reverse) {
this.capacity = capacity;
heap = new int[capacity];
this.reverse = reverse;
}
private int compare(int a, int b) {
if (reverse)
return b - a;
return a - b;
}
public void insert(int key) {
if (isFull()) {
throw new IndexOutOfBoundsException("Out of given capacity");
}
heap[size] = key;
swim(size++);
}
// private void rightshift(int parent, int position) {
// for (int i = position; i > parent; i--) {
// if (compare(heap[i], heap[i - 1]) > 0)
// swap(i, i - 1);
// }
// }
private void swim(int position) {
int parent = (position) / 2;
if (position > 0 && compare(heap[parent], heap[position]) < 0) {
swap(parent, position);
// rightshift(parent, position);
swim(parent);
}
}
private void sink(int position) {
int left = position * 2 + 1;
int right = position * 2 + 2;
int largest = position;
if (left < size && compare(heap[position], heap[left]) < 0) {
largest = left;
}
if (right < size && compare(heap[position], heap[right]) < 0) {
largest = right;
}
if (largest != position) {
swap(largest, position);
sink(largest);
}
}
public int getMin() {
if (isEmpty()) {
throw new IllegalStateException("No Data available");
}
if (reverse) {
return heap[size - 1];
}
return heap[0];
}
public int getMax() {
if (isEmpty()) {
throw new IllegalStateException("No Data available");
}
if (reverse) {
return heap[0];
}
return heap[size - 1];
}
public void delTop() {
if (isEmpty()) {
throw new IllegalStateException("No Data Available to delete");
}
swap(0, size - 1);
size--;
sink(0);
}
public void delMin() {
if (isEmpty()) {
throw new IllegalStateException("No Data Available to delete");
}
if (reverse) {
throw new RuntimeErrorException(null, "You Initialized a Min heap");
}
swap(getMin(), 0);
size--;
sink(0);
}
public void delMax() {
if (isEmpty()) {
throw new IllegalStateException("No Data Available to delete");
}
if (!reverse) {
throw new RuntimeErrorException(null, "You Initialized a Max heap");
}
swap(getMax(), 0);
size--;
sink(0);
}
public int size() {
return size - 1;
}
public boolean isFull() {
return size - 1 == capacity;
}
public boolean isEmpty() {
return size == 0;
}
private void swap(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
@Override
public String toString() {
int[] items = Arrays.copyOf(heap, size);
return Arrays.toString(items);
}
}
输出量:
最小堆数:10、20、40、30、80、60、70、50、90、100
最大堆数:100、90、80、60、70、10、50、30、20、40
问题描述:
我正在努力在Java中实现min-heap和max-heap,但我遇到了正确排序数组的问题。让我通过一个例子来解释这个问题:
假设我们有一个数组,初始化如下:{0,0,0}(最大堆)。
我们插入70,arr变成{70,0,0}。不会做进一步的更改。我们插入50,arr变成{70,50,0}。不会做进一步的更改。我们插入80,arr变成{70,50,80}。在这里,80大于它的父节点(70),所以我们交换它们。在这个交换之后,变成{80,50,70}。现在,数组仍然没有正确排序。我试图通过引入一个右移函数来解决这个问题,但它并没有像预期的那样工作。
我尝试过的:
我已经实现了min-heap和max-heap的基本结构,但我认为问题主要与swim、sink和rightshift函数有关。
我对代码进行了修改,包括调整比较函数和修改swim和sink函数。但是,数组仍然没有按预期进行排序。
问:
我需要帮助修复sink、swim和rightshift函数或任何其他必要的更改,以确保数组在min-heap和max-heap实现中正确排序。你能检查一下我的代码,并提供指导,说明需要修改什么才能实现这一目标吗?
1条答案
按热度按时间c0vxltue1#
现在,数组仍然没有正确排序。
堆 * 不是 * 一个排序的数组,堆排序也不仅仅是构建一个堆。
这也意味着您不能同时拥有
getMin
和getMax
函数。您只能获得堆的“顶部”作为可靠值。数组中的最后一个值不一定是另一个极端。出于同样的原因,你不能同时拥有delMin
和delMax
函数,只有一个delTop
函数,像这样:堆排序包括构建一个堆,然后重复地从一个大小减小的堆中删除顶部,并将提取的值放入一个排序分区(在末尾)。
Bug
除了上面的注解,
sink
函数的这一部分还有一个错误:第二个
if
条件将position
处的条目与right
处的条目进行比较,但它应该比较largest
处的条目。所以正确的是:函数
size()
和isFull()
也有一个问题,因为它们使用size - 1
,而它们应该使用size
。以下是对两个函数的修正:实现堆排序
要实现堆排序,可以添加以下方法:
在main函数中调用这个
sort
方法:现在它将按排序顺序打印出值。