二叉堆总是一颗完全二叉树;堆的某个节点的值总是不大于或不小于其节点的值。
按照数据的排列方式可以分为两种:最大堆和最小堆。
最大堆(大顶堆):父结点的键值总是大于或等于任何一个子节点的键值;
最小堆(小顶堆):父结点的键值总是小于或等于任何一个子节点的键值。
----------------【一般堆用于查找、删除、插入操作。完成二叉树是从上到下,都是按照节点拥有度为2的思想添加子节点。因此实际二叉堆加入一个元素,需要时刻调整来保证满足上面的性质。】
二叉堆数据结构:
使用链表List即可。
二叉堆添加过程思路:
数据先放在末尾,然后和其父节点进行比较,以便交换,直到不能交换。
二叉堆删除过程思路:
先找到要删除的节点,然后该节点和末尾节点交换【这样删除的节点自动没了】,然后比较交换的节点的两个子节点,按照二叉堆性质进行挪动,直到不能挪动。
满足具体业务的数据对象
public class HeapStructure> {
/**
* 标识
*/
private String id;
/**
* 具体数据
*/
private T data;
public HeapStructure(String id,T data){
this.id = id;
this.data = data;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
最大堆方法
public class MaxHeap {
private List maxHeapList;
public MaxHeap(){
maxHeapList = new ArrayList<>();
}
/**
* 堆大小
*/
public int size(){
return maxHeapList.size();
}
/**
* 查询
*/
public HeapStructure getByIndex(int index){
return maxHeapList.get(index);
}
/**
* 返回结果
*/
public List getMaxHeapList(){
return maxHeapList;
}
/**
* 正常添加在list后面,然后和对应父节点进行比较,调整位置
*/
public void insert(HeapStructure e){
int oldSize = maxHeapList.size();
maxHeapList.add(e);
//向上调整 【由于是从后添加,所以是向上调整】
filterup(oldSize);
}
/**
* 向上调整
*/
private void filterup(int start){
int c = start;
int p = (c - 1) >> 1;
while (c > 0){//从第二个节点开始调整
if(maxHeapList.get(c).getData().compareTo(maxHeapList.get(p).getData()) > 0){
//需要调整
HeapStructure temp = maxHeapList.get(p);
maxHeapList.set(p,maxHeapList.get(c));
maxHeapList.set(c,temp);
c = p;
p = (c - 1) >> 1;
}else
break;
}
}
/**
* start是开始调整位置,end是最终位置
*/
private void filterDown(int start,int end){
int c = start;
int lfIndex = (c << 1) + 1;
HeapStructure cData = maxHeapList.get(c);
//虽然新替换的值比原值小,但都比左右节点数据大
if(cData.getData().compareTo(maxHeapList.get(lfIndex).getData()) >= 0
&& cData.getData().compareTo(maxHeapList.get(lfIndex+1).getData()) >= 0){
return;
}
while (lfIndex <= end){
//只有左节点,直接比较后是否交换,退出
if(lfIndex == end){
if(maxHeapList.get(c).getData().compareTo(maxHeapList.get(lfIndex)) < 0){
maxHeapList.set(c,maxHeapList.get(lfIndex));
c = lfIndex;
}
break;
}
//左右节点找到最大的
if(maxHeapList.get(lfIndex).getData().compareTo(maxHeapList.get(lfIndex+1).getData()) < 0){
lfIndex ++;
}
if(cData.getData().compareTo(maxHeapList.get(lfIndex).getData()) >= 0){
break;
}
//将大的值上移原本替换位置
maxHeapList.set(c,maxHeapList.get(lfIndex));
c = lfIndex;
lfIndex = (c << 1) + 1;
}
//最终找到位置
maxHeapList.set(c,cData);
}
/**
* 找到对应的位置
*/
private int indexOf(HeapStructure e){
//根据id去匹配找到对应数据
int i = -1;
for (HeapStructure temp : maxHeapList){
++i;
if(e.getId().equals(temp.getId())){
return i;
}
}
return -1;
}
/**
* 删除节点
*/
private int remove(HeapStructure e){
if(maxHeapList.isEmpty()){
return -1;
}
//找到要删除元素位置,和末尾元素交互
// 如果“替换后元素”比之前元素大,那么一定大于左右子节点;只需要往上调整
// 如果“替换后元素”比之前元素小,那么需要往下调整
int endIndex = maxHeapList.size();
int index = indexOf(e);
HeapStructure replaceDta = maxHeapList.get(endIndex - 1);
maxHeapList.set(index,replaceDta);
maxHeapList.remove(endIndex - 1);
if(maxHeapList.size() > 0){
if(replaceDta.getData().compareTo(e.getData()) > 0){
filterup(index);
}else
filterDown(index,maxHeapList.size() - 1);
}
return 1;
}
/*
* 替换节点
/
public void replace(HeapStructure data){
maxHeapList.set(0,data);
if (maxHeapList.size() > 1)
filterDown(0, maxHeapList.size()-1);
}
public static void main(String[] args) {
int a[] = {90, 80, 30, 75, 50, 25, 29, 60, 62,49,20,24,23,27,26,61};
MaxHeap maxHeap = new MaxHeap();
for(int i=0; i
可以使用最大堆实现。最大堆的思想是:所有的子节点都要比父节点大于或等于。所以在插入数据时,保证list.get(0)是当前最大堆的最大元素,如果新数据进人,先和list.get(0)比较,比该值大,那么直接抛弃,如果比该值小,那么直接替换list(0)位置的元素,然后向下调整机制。
public class MaxHeapExample1 {
//最大堆
private MaxHeap maxHeap;
//最大容量限制
private int capacity;
public MaxHeapExample1(int capacity){
maxHeap = new MaxHeap();
this.capacity = capacity;
}
//添加
public boolean insert(HeapStructure e){
if(capacity <= 0){
return false;
}
if(maxHeap.size() < capacity){
maxHeap.insert(e);
return true;
}
//新值和min比较 【第一个位置元素】
HeapStructure currentMin = maxHeap.getByIndex(0);
if(currentMin.getData().compareTo(e.getData()) > 0){
//替换新值
maxHeap.replace(e);
}
return true;
}
public static void main(String[] args) {
int a[] = {80, 40, 90, 60, 90, 54,75,71,83,70,70, 10, 50, 20};
MaxHeapExample1 tree = new MaxHeapExample1(5);
for(int i=0; i