数据结构_二叉堆普通操作

来源:互联网 发布:李刚 疯狂java 编辑:程序博客网 时间:2024/05/17 00:57

二叉堆是一个完全二叉树(只是一种这样的认识结构,实质是数组),其每个节点都小于其2个子节点。一棵高为h的完全二叉树拥有的节点数市2^h 到 2^(h+1) - 1。对完全二叉树一层一层按从左到右的顺序编上号,那么若一个完全二叉树节点编号为n,则其左节点编号为2*n,右节点编号为2*n+1.所以完全二叉树可以用数组来表示,从位置1开始存储元素,因为通过其规律很容易获得其子节点,且通过二叉堆的性质能做到低代价的插入删除消耗。

插入操作:

采取了一种上滤的策略,一开始在数组末尾位置设置一个插入位置,当父节点存在且比插入节点大的时候,则将父节点值移到插入位置,插入位置变为父节点位置。

            int hole = ++size;
            if(array.Length < size + 1) {      //当数组已经满了时 扩充数组
                extensionArray();
            }
            while (hole/2 > 0 && array[hole/2].CompareTo(e) > 0) { //父节点存在且父节点大于插入节点 则将插入位置上移
                array[hole] = array[hole / 2];
                hole = hole / 2;
            }
            array[hole] = e;                    //插入到插入位置 

删除最小值操作:

采取了下滤的策略,堆最小值是数组的第一个元素,先将该最小值拿出来,将位置1设为删除位置,然后判断子节点,当左右子节点都存在时,从2个子节点中找出较小的放在删除位置,位置变为该较小节点原位置。当只有一个节点,则直接将子节点放在删除位置,删除位置变为子节点原位置。没有子节点则将最后一个节点移动到该位置。

            if (size == 0) throw new IndexOutOfRangeException();  //堆没有元素 返回Exception
            E min = array[1];
            int n = 1;
            while (true) {
                if (2 * n > size) {                     //2个子节点都不存在
                    break;
                }
                else if (2 * n + 1 > size) {           //有1个子节点,因为这个子节点就是最后个节点,所以结束方法
                    array[n] = array[2 * n];
                    n = 2 * n;
                    size--;
                    return min;
                }
                if (array[2 * n].CompareTo(array[2 * n + 1]) > 0)   //2个子节点都存在 找出较小的下滤
                {
                    array[n] = array[2 * n + 1];
                    n = 2 * n + 1;
                }
                else {
                    array[n] = array[2 * n];
                    n = 2 * n;
                }
            }
            array[n] = array[size];                     //将最后节点移动到高位置
            size--;
            return min;

原创粉丝点击