堆是一个彻底二叉树结构(除了最底下一层,其余层全是彻底平衡的),若是每一个结点都大于它的两个孩子,那么这个堆是有序的。java
二叉堆是一组可以用堆有序的彻底二叉树排序的元素,并在数组中按照层级存储(不用数组的第一个位置)
node![]()
循环,每次比较本身和父亲,若是比父亲大就交换,直到root。
算法
先把元素加入数组的最后一个位置,而后进行上浮到正确位置
数组
循环,每次比较本身和两个孩子,若是比孩子小就交换,若是比两个孩子都小,就交换到两个里面较大的一个。直到叶子。
markdown
先把根元素与最后一个元素交换,删除最后一个元素,而后从根开始下沉到正确位置。less
/** * * @author rocky */
public class MaxPQ<Key extends Comparable<Key>> {
private Key[] pq;
private int N;
public MaxPQ(int capacity) {
pq = (Key[]) new Comparable[capacity + 1];
}
public boolean isEmpty() {
return N == 0;
}
public void insert(Key key)
{
N++;
pq[N] = key;
swim(N);
}
public Key delMax() {
Key max = pq[1]; //get the max element
exch(1, N); //exchange between the root and the last element
N--;
sink(1); //sink to the right place
pq[N+1] = null; //delete
return max;
}
private void swim(int k)
{
while(k > 1 && less(k/2, k))
{
exch(k, k/2);
k /= 2;
}
}
private void sink(int k) {
while(k*2 <= N) //if this node has left child
{
int child = k * 2;
if (child < N && less(child, child + 1)) { //if the left child is less than the right child
child = child + 1; //change child to the right child
}
if (less(k, child)) {
exch(k, child);
}
k = child;
}
}
private boolean less(int i, int j) {
return pq[i].compareTo(pq[j]) < 0;
}
private void exch(int i, int j) {
Key t = pq[i];
pq[i] = pq[j];
pq[j] = t;
}
}
咱们算法的前提是用户不会改变队列的元素,若是用户能改变队列的元素,那么队列成立的条件就会破坏,
不可变的数据类型,就是说一个实例一旦创建,就不能够改变。java里不少类型都是不可变的。
this
这有不少好处,可是坏处就是若是你须要改变值必需要新建一个对象。
spa