使用数组保存二叉树结构,方式即将二叉树层序遍历放在数组中
最大堆的实现:
package datastructure.heap;
import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
public class MaxHeap {
List<Integer>data;
public MaxHeap(int size){
this.data=new ArrayList<>(size);
}
public MaxHeap(int[]arr){
data=new ArrayList<>(arr.length);
for (int i:arr
){
data.add(i);
}
for (int i = parent(data.size()-1); i >= 0; i--) {
siftDown(i);
}
}
//向堆中插入一个元素
private void add(int k){
data.add(k);
siftUp(k);
}
//取出堆中的最大元素
public int extractMax(){
if (data.isEmpty()){
throw new NoSuchElementException("heap is empty!cannot extract!");
}
return data.get(0);
}
//元素的上浮造作
private void siftUp(int k) {
// 上浮操作的终止条件: 已经走到根节点 || 当前节点值 <= 父节点值
// 循环的迭代条件 : 还存在父节点并且当前节点值 > 父节点值
while (k > 0 && data.get(k) > data.get(parent(k))) {
// 交换当前节点和父节点值
swap(k,parent(k));
k = parent(k);
}
}
//shiftdown操作(下沉)
private void siftDown(int k) {
// 还存在子树
while (liftChild(k) < data.size()) {
int j = liftChild(k);
// 判断一下是否有右子树
if (j + 1 < data.size() && data.get(j + 1) > data.get(j)) {
// 此时右树存在且大于左树的值
j = j + 1;
}
// 此时j就对应左右子树的最大值
// 和当前节点k去比较
if (data.get(k) >= data.get(j)) {
// 下沉结束
break;
}else {
swap(k,j);
k = j;
}
}
}
@Override
public String toString() {
return "MaxHeap{" +
"data=" + data +
'}';
}
//根据索引求出父节点
private int parent(int k){
return (k-1)>>1;
}
//根据索引得到左子树
public int liftChild(int k){
return (k<<1)+1;
}
public int rightChild(int k){
return (k<<1)+2;
}
private void swap(int i, int j) {
int temp = data.get(i);
data.set(i,data.get(j));
data.set(j,temp);
}
public boolean isEmpty() {
return data.size() == 0;
}
public static void main(String[] args) {
int []arr={1,2,3,4,5,6,7,8,9,10};
MaxHeap maxHeap=new MaxHeap(arr);
System.out.println(maxHeap);
}
}