添加元素(Sift Up)
不断往上比较是否大于父节点元素,一直比较小于父节点的时候,位置找到了
这就有点像上浮,不断往上交换
交换代码
//交换动态数组中的位置
public void swap(int i,int j){
if(i< 0 || i>=size || j<0 || j>=size)
throw new IllegalArgumentException("下标错误");
E t=data[i];
data[i]=data[j];
data[j]=t;
}
添加元素,添加末尾,
然后比较一直循环比较,交换
//向堆中添加元素
public void add(E e){
data.addLast(e);
siftUp(data.getSize()-1);
}
//上浮siftUp
private void siftUp(int k){
while(k >0 && data.get(parent(k)).compareTo(data.get(k)) < 0){
data.swap(k,parent(k));//交换位置
k=parent(k);
}
}
取出元素(Sift Down)
取出元素和上浮一样的思路,但是是下浮,
不断往下比较,一直找到大于左节点、右节点的位置,结束
取出最大的元素,也就是队首,取出来之后就为0然后与队尾进行交换,然后循环比较
//看堆中的最大元素
public E findMax(){
if(data.getSize() ==0)
throw new IllegalArgumentException("没有元素");;
return data.get(0);
}
//取出堆中最大元素
public E extractMax(){
E ret =findMax();
data.swap(0, data.getSize()-1);//交换最后的元素
data.removeLast();//删除最后一个元素
siftDown(0);//下浮,不断往下面进行匹配 直到找到符合的位置
return ret;
}
//下浮 和上浮一样的思路 只是往下一直循环进行交换位置
private void siftDown(int k){
//k的左节点小于最大元素 循环条件
while(leftChild(k) < data.getSize()){
int j=leftChild(k);
if(j+1 <data.getSize() &&
data.get(j+1).compareTo(data.get(j)) >0)//左节点小于右节点 条件允许
j=rightChild(k);
//data[j]是leftChild和rightChild中最大值
//当父节点都大于左节点和右节点都符合 位置就找到了 循环结束
if(data.get(k).compareTo(data.get(j)) >=0)
break;
//否则一直交换
data.swap(k, j);
k=j;
}
}