小根堆java_java使用小根堆实现优先级队列的几种方式

写在之前

1.自定义实现采用数组作为内部数据结构

2.内部数组通过resize方法进行扩容,每次只是简单的扩展为原来的2倍

3.集中实现方式的主要区别在于siftDown方法

4.以下给出关键代码,更多详细信息请看附件源码

?

实现方式一(递归实现)

关键代码:

class="java" name="code"> @Override

protected void siftDown(int index)

{

int len = totalCount - 1;

while(left(index) <= len)

{

int left = left(index);

int right = right(index);

if(left > len)

{

break;

}

int currentMin = left;

if(right <= len && arr[currentMin] > arr[right])

{

currentMin = right;

}

if(arr[currentMin] >= arr[index])

{

break;

}

swap(arr, currentMin, index);

index = currentMin;

}

}

?

实现方式二(循环实现)

关键代码:

@Override

protected void siftDown(int index)

{

int len = totalCount - 1;

while(left(index) <= len)

{

int left = left(index);

int right = right(index);

if(left > len)

{

break;

}

int currentMin = left;

if(right <= len && arr[currentMin] > arr[right])

{

currentMin = right;

}

if(arr[currentMin] >= arr[index])

{

break;

}

swap(arr, currentMin, index);

index = currentMin;

}

}

?

实现方式三(直接构建堆)

关键代码:

@Override

protected void siftDown(int index)

{

int len = totalCount - 1;

while(left(index) <= len)

{

int left = left(index);

int right = right(index);

if(left > len)

{

break;

}

int currentMin = left;

if(right <= len && arr[currentMin] > arr[right])

{

currentMin = right;

}

if(arr[currentMin] < arr[index])

{

swap(arr, currentMin, index);

}

//进入下一个非叶子节点

index++;

}

}

?

实现方式四(JDK中的实现)

1.siftUp方法:

protected void siftUp(int k, int x)

{

while (k > 0)

{

int parent = parent(k);

int e = arr[parent];

if (x >= e)

break;

arr[k] = e;

k = parent;

}

arr[k] = x;

}

?2.siftDown方法:

/**

* 指定index位置的值为x,并为x在堆中找到合适位置

* @param index

* @param x

*/

private void siftDown(int index, int x)

{

int half = totalCount >>> 1;

while (index < half)

{

int currentMin = left(index);

int right = right(index);

if (right < totalCount && arr[currentMin] > arr[right])

currentMin = right;

if (x <= arr[currentMin])

break;

//将index位置设置为最小节点值

arr[index] = arr[currentMin];

//迭代

index = currentMin;

}

//将最终值放入合适位置

arr[index] = x;

}

?

其他的一下关键方法

1.siftUp方法:

@Override

protected void siftUp(int index)

{

int parent = parent(index);

while(index > 0 && arr[index] < arr[parent])

{

swap(arr, index, parent);

index = parent;

parent = parent(index);

}

}

?2.add方法:

@Override

public boolean add(int ele)

{

if(totalCount == arr.length)

{

//扩容

grow();

}

int i = totalCount;

arr[i] = ele;

if(totalCount == 1)

{

return true;

}

//调整元素位置确保为小根堆

siftUp(i);

totalCount++;

return true;

}

?3.poll方法:

@Override

public int poll()

{

int result = arr[0];

arr[0] = arr[--totalCount];

siftDown(0);

return result;

}

?5.remove方法:

@Override

public int remove(int ele)

{

//内部数据为空

if(totalCount < 1)

{

return -1;

}

//计算元素位置

int index = indexOf(ele);

if(index < 0)

{

return -1;

}

return removeAt(index);

}

?6.removeAt方法:

@Override

protected int removeAt(int idx)

{

if(idx < 0 || idx >= totalCount)

{

return -1;

}

int result = arr[idx];

//将删除元素与最后一个元素交换位置

if(idx != totalCount -1)

{

arr[idx] = arr[totalCount - 1];

}

//位置交换之后队列长度减一

totalCount--;

//如果队列长度大于1,而且删除的元素位置不在队尾则重新调整堆

if(totalCount > 1 && idx != totalCount)

{

siftDown(idx);

}

return result;

}

?

?

?

heap.zip (7.7 KB)

下载次数: 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值