Skip to content

Commit

Permalink
堆的实现
Browse files Browse the repository at this point in the history
  • Loading branch information
Xikl committed Jan 3, 2019
1 parent e432175 commit 5ff16ed
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/main/java/com/ximo/datastructuresinaction/array/Array.java
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,21 @@ public void removeElement(E element) {
}
}

/**
* 交换元素
*
* @param prev 元素所在索引
* @param next 下一个所在的索引位置
*/
public void swap(int prev, int next) {
if (prev < 0 || prev > size || next < 0 || next > size) {
throw new IndexOutOfBoundsException();
}
E temp = data[prev];
data[prev] = data[next];
data[next] = temp;
}

@Override
public String toString() {
StringBuilder res = new StringBuilder();
Expand Down
115 changes: 115 additions & 0 deletions src/main/java/com/ximo/datastructuresinaction/heap/MaxHeap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.ximo.datastructuresinaction.heap;

import com.ximo.datastructuresinaction.array.Array;

/**
* 大顶堆
* 当数组索引从1开,那么
* parent = i / 2
* leftChild = i * 2
* rightChild = i * 2 + 1
*
* 当数组索引从0开始
* parent = (i - 1) / 2
* leftChild = i * 2 + 1
* rightChild = i * 2 + 2
*
* @author xikl
* @date 2019/1/3
*/
public class MaxHeap<E extends Comparable<E>> {

private Array<E> data;

public MaxHeap(int capacity) {
data = new Array<>(capacity);
}

public MaxHeap() {
data = new Array<>();
}

public int size() {
return data.getSize();
}

public boolean isEmpty() {
return data.isEmpty();
}

/**
* 获得父类的索引位置
*
*
*
* @param index 索引位置
* @return 父亲索引
*/
public int getParentIndex(int index) {
if (index == 0) {
throw new IllegalArgumentException("index-0 doesn't have parent.");
}
return (index - 1) / 2;
}

public int getLeftChildIndex(int index) {
return index * 2 + 1;
}

public int getRightChildIndex(int index) {
return index * 2 + 2;
}

public void add(E e) {
data.addLast(e);
siftUp(data.getSize() - 1);
}

public void siftUp(int index) {
int parentIndex = getParentIndex(index);
// 比较父亲与自己的大小
while (index > 0 && data.get(parentIndex).compareTo(data.get(index)) < 0) {
// 交换
data.swap(index, parentIndex);
index = parentIndex;
parentIndex = getParentIndex(index);
}
}

public E findMax() {
return data.getFirst();
}

public E extractMax() {
E ret = findMax();
// 将堆中最大的元素和最小的元素交换位置
data.swap(0, data.getSize() - 1);
data.removeLast();
// 进行下沉操作
siftDown(0);
return ret;
}

public void siftDown(int index) {
while (getLeftChildIndex(index) < data.getSize()) {
int maxOnLeftAndRightValueIndex = getMaxOnLeftAndRightValueIndex(index);
if (data.get(index).compareTo(data.get(maxOnLeftAndRightValueIndex)) >= 0) {
break;
}
data.swap(index, maxOnLeftAndRightValueIndex);
index = maxOnLeftAndRightValueIndex;
}
}

public int getMaxOnLeftAndRightValueIndex(int index) {
int leftChildIndex = getLeftChildIndex(index);
// 其实也等于 leftChildIndex + 1
int rightChildIndex = getRightChildIndex(index);

boolean leftLessThanRight = rightChildIndex < data.getSize()
&& data.get(leftChildIndex).compareTo(data.get(rightChildIndex)) < 0;
return leftLessThanRight ? rightChildIndex : leftChildIndex;
}


}

0 comments on commit 5ff16ed

Please sign in to comment.