其实在写二叉堆实现的时候,已经在堆排序中了解了二叉堆,所以在这里不再详细讲解二叉堆的性质,有兴趣的可以看一看这里:堆排序(最大堆)的理解和实现(Java)
代码实现:
package 二叉堆;
import java.util.ArrayList;
/**
* 最大堆
* @author lishanlei
*
*/
public class MaxHeap<T extends Comparable<T>> {
//用List来存储堆
public ArrayList<T> mHeap;
public MaxHeap() {
this.mHeap = new ArrayList<T>();
}
/**
* 最大堆的上泛
* 数组实现的堆中,第n个节点的左孩子的索引值是(2n + 1),第n个节点的右孩子的索引值为(2n + 2)
* @param start 被上调节点的起始位置(一般是数组中最后一个元素的索引)
*/
private void filterup(int start) {
int current = start; //当前节点的位置
int father = (current - 1) / 2; //当前节点父节点的位置
T cData = this.mHeap.get(current); //当前节点的值
while(current > 0) {
int tmp = this.mHeap.get(father).compareTo(cData);
if(tmp > 0) {
break;
}
else {
this.mHeap.set(current, this.mHeap.get(father));
current = father;
father = (father - 1) / 2;
}
}
this.mHeap.set(current, cData);
}
/**
* 最大堆的下泛调整
* @param start 被下调节点的索引值(一般为0,表示从第一个开始)
* @param end 截至范围(一般为数组中最后一个元素的索引)
*/
private void filterdown(int start, int end) {
int current = start; //当前节点的位置
int left = (current * 2) + 1; //左孩子节点的位置
T cData = this.mHeap.get(current); //当前节点的值
while(left < end) {
int cmp = this.mHeap.get(left).compareTo(this.mHeap.get(left + 1));
if(left < end && cmp < 0) {
++left;
}
cmp = cData.compareTo(this.mHeap.get(left));
if(cmp > 0) {
break;
}
else {
this.mHeap.set(current, this.mHeap.get(left));
current = left;
left =(2 * left) + 1;
}
}
this.mHeap.set(current, cData);
}
/**
* 二叉树的插入操作
* @param data
*/
public void insert(T data) {
int size = this.mHeap.size();
this.mHeap.add(data);
this.filterup(size);
}
/**
* 二叉树的删除操作
* @param data
* @return
*/
public int remove(T data) {
if(this.mHeap.isEmpty() == true) {
return -1;
}
int index = this.mHeap.indexOf(data);
if(index == -1) {
return -1;
}
int size = this.mHeap.size();
this.mHeap.set(index, this.mHeap.get(size - 1));
this.mHeap.remove(size - 1);
if(this.mHeap.size() > 1) {
this.filterdown(index, this.mHeap.size() - 1);
}
return 1;
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < this.mHeap.size(); i++) {
sb.append(this.mHeap.get(i) + ", ");
}
return sb.toString();
}
public static void main(String[] args) {
int i;
int a[] = {10, 40, 30, 60, 90, 70, 20, 50, 80};
MaxHeap<Integer> tree=new MaxHeap<Integer>();
System.out.printf("== 依次添加: ");
for(i=0; i<a.length; i++) {
System.out.printf("%d ", a[i]);
tree.insert(a[i]);
}
System.out.printf("\n== 最 大 堆: %s", tree);
i=85;
tree.insert(i);
System.out.printf("\n== 添加元素: %d", i);
System.out.printf("\n== 最 大 堆: %s", tree);
i=90;
tree.remove(i);
System.out.printf("\n== 删除元素: %d", i);
System.out.printf("\n== 最 大 堆: %s", tree);
System.out.printf("\n");
}
}
测试:
== 依次添加: 10 40 30 60 90 70 20 50 80
== 最 大 堆: 90, 80, 70, 60, 40, 30, 20, 10, 50,
== 添加元素: 85
== 最 大 堆: 90, 85, 70, 60, 80, 30, 20, 10, 50, 40,
== 删除元素: 90
== 最 大 堆: 85, 80, 70, 60, 40, 30, 20, 10, 50,
代码实现:
package 二叉堆;
import java.util.ArrayList;
/**
* 最小堆
* @author lishanlei
*
* @param
*/
public class MinHeap<T extends Comparable<T>> {
public ArrayList<T> mHeap;
public MinHeap() {
this.mHeap = new ArrayList<T>();
}
/**
* 最小堆的上泛
* @param start
*/
public void filterup(int start) {
int current = start;
int father = (current - 1) / 2;
T cData = this.mHeap.get(current);
while(current > 0) {
int cmp = this.mHeap.get(father).compareTo(cData);
if(cmp <= 0) {
break;
}
else {
this.mHeap.set(current, this.mHeap.get(father));
current = father;
father = (father - 1) / 2;
}
}
this.mHeap.set(current, cData);
}
/**
* 插入数据到最小堆
* @param data
*/
public void insert(T data) {
int size = this.mHeap.size();
this.mHeap.add(data);
this.filterup(size);
}
/**
* 最小堆的下泛
* @param start
* @param end
*/
public void filterdown(int start, int end) {
int current = start;
int left = (2 * current) + 1;
T cData = this.mHeap.get(current);
while(left <= end) {
int tmp = this.mHeap.get(left).compareTo(this.mHeap.get(left + 1));
if(left < end && tmp > 0) {
left++;
}
tmp = cData.compareTo(this.mHeap.get(left));
if(tmp <= 0) {
break;
}
else {
this.mHeap.set(current, this.mHeap.get(left));
current = left;
left = 2 * left + 1;
}
}
this.mHeap.set(current, cData);
}
public int remove(T data) {
if(this.mHeap.isEmpty() == true) {
return -1;
}
int index = this.mHeap.indexOf(data);
if(index == -1) {
return -1;
}
int size = this.mHeap.size();
this.mHeap.set(index, this.mHeap.get(size - 1));
this.mHeap.remove(size - 1);
if(this.mHeap.size() > 1) {
this.filterdown(index, this.mHeap.size() - 1);
}
return 1;
}
//打印堆
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i=0; i<mHeap.size(); i++)
sb.append(mHeap.get(i) +" ");
return sb.toString();
}
public static void main(String[] args) {
int i;
int a[] = {80, 40, 30, 60, 90, 70, 10, 50, 20};
MinHeap<Integer> tree=new MinHeap<Integer>();
System.out.printf("== 依次添加: ");
for(i=0; i<a.length; i++) {
System.out.printf("%d ", a[i]);
tree.insert(a[i]);
}
System.out.printf("\n== 最 小 堆: %s", tree);
i=15;
tree.insert(i);
System.out.printf("\n== 添加元素: %d", i);
System.out.printf("\n== 最 小 堆: %s", tree);
i=10;
tree.remove(i);
System.out.printf("\n== 删除元素: %d", i);
System.out.printf("\n== 最 小 堆: %s", tree);
System.out.printf("\n");
}
}
测试:
== 依次添加: 80 40 30 60 90 70 10 50 20
== 最 小 堆: 10 20 30 50 90 70 40 80 60
== 添加元素: 15
== 最 小 堆: 10 15 30 50 20 70 40 80 60 90
== 删除元素: 10
== 最 小 堆: 15 20 30 50 90 70 40 80 60
参考:https://www.cnblogs.com/skywang12345/p/3610390.html