算法和数据结构(7)堆

堆有两个特性

  1. 用数组表示的完全二叉树
  2. 任一结点的关键(root)字是其所有子树所有结点的最大值(最大值)
  3. 最大堆:最大值,下图在这里插入图片描述
  4. 最小堆:最小值,下图在这里插入图片描述
  5. 特性: 路径有序在这里插入图片描述
  6. 目的,实现优先队列,取出元素按优先级,而非插入的顺序;

插入操作理解:插入这个数组表达的完全二叉树的最末尾,然后对比其父结点,是否大于,大于则互换位置,小于则break;

删除操作理解:如图删除max即index=1时的元素,

  1. 最末尾元素替换index=1的元素,然后最末尾替换它;
  2. 调整最末尾的数字的位置;如图示;在这里插入图片描述在这里插入图片描述
public class Heap {
    int[] elements; //存储数组
    int size;    //当前元素数量
    int capacity; //最大容量

    public Heap(int capacity) {
        this.capacity = capacity;
        elements = new int[capacity + 1]; //从index =1 开始存储, 0 为稍定
        elements[0] = Integer.MAX_VALUE;
        size = 0;
    }

    public void insert(int element) {
        if (isFull()) throw new RuntimeException("full");
        int index = ++size; // 实际存储从1 开始存入数组;
        for (; elements[index / 2] < element; index /= 2) {
            elements[index] = elements[index / 2];
        }
        elements[index] = element;
    }

    public int deleteMax() {
        if (isEmpty())
            throw new RuntimeException("empty");
        int maxItem = elements[1];
        int temp = elements[size--];
        int parent = 1;
        for (int child = 0; parent * 2 < size; parent=child) {
            child = parent*2;
            if (parent!=size && elements[child]<elements[child+1])
                child++;
            if (temp>elements[child]) break;
            else
                elements[parent] = elements[child];
        }
        elements[parent] = temp;
        return maxItem;
    }
}

哨兵的意义

哨兵取最大值,在insert方法中,i=1时,i/2=0,elements[i] = max_int;可以增加for循环的效率;

堆的建立

在这里插入图片描述
思想理解:
若图所述的数组(完全二叉树)并非一个堆,从最后一个开始慢慢构建一个堆,利用删除的思想,逐步调整,找最大的值/最小值,放入结点中;即可构架最大堆/最小堆;

发布了17 篇原创文章 · 获赞 0 · 访问量 366

猜你喜欢

转载自blog.csdn.net/qq_32193775/article/details/104115268