实现上一篇博客(http://blog.csdn.net/buleriver/article/details/38469977)说的D堆。假设把mD设置成2。D堆就退化成二叉堆,也就是说。二叉堆是D堆的一种情况。
public class DHeap { public static final int INIT_CAPACITY = 10; private int[] mArray; private int mLength; private final int mD; public DHeap(int d) { mArray = new int[INIT_CAPACITY + 1]; mLength = 0; mD = d; } public int getParentIndex(int index) { return (index - 2 + mD) / mD; } public int getChildIndex(int pIndex, int childIndex) { return mD * (pIndex - 1) + 2 + childIndex; } private void expandArray(int length) { int[] arr = new int[length]; System.arraycopy(mArray, 1, arr, 1, mLength); mArray = arr; } /** * 自下而上,把value放到最后一个,然后一直和其父节点交换,找到合适的位置 */ public void insert(int value) { if (mLength >= mArray.length - 1) { expandArray(mArray.length * 2); } mArray[++mLength] = value; int index = mLength; int parentIndex = getParentIndex(index); while (parentIndex > 0) { int currentValue = mArray[index]; int parentValue = mArray[parentIndex]; if (currentValue < parentValue) { mArray[parentIndex] = currentValue; mArray[index] = parentValue; index = parentIndex; parentIndex = getParentIndex(index); } else { break; } } } public void deleteMin() { if (mLength <= 0) { return; } else if (mLength == 1) { mLength--; } else { mArray[1] = mArray[mLength]; int index = 1; mLength--; while (true) { int value = mArray[index]; int minIndex = -1; // 最小孩子的数组索引 boolean lastLevel = false; // 是否已经到了最底层 int firstChildIndex = getChildIndex(index, 0); int lastChildIndex = firstChildIndex + mD; for (int childIndex = firstChildIndex; childIndex < lastChildIndex; childIndex++) { // 找到最小的孩子 if (childIndex > mLength) { // 已经到了最后一个 lastLevel = true; break; } int childValue = mArray[childIndex]; if (value > childValue) { value = childValue; minIndex = childIndex; } } if (minIndex < 0) { // 已经符合d堆的性质,不须要置换了 break; } else { // 须要置换 mArray[minIndex] = mArray[index]; mArray[index] = value; index = minIndex; } if (lastLevel) { // 已经到了最底层 break; } } } } }