堆和堆排序

堆,顾名思义,小山堆,最标准的形状就是金字塔

			1
	2               3
4		5		6		  7		
		这个三角就是简易的堆

我们可以看出堆的关系时根节点下有两个子节点构成,根节点为k,左孩子就是2k,右孩子就是2k+1,颠倒来讲,当孩子节点的索引为k,那么它的母节点的索引为k/2,这个概念是我们接下来讨论shiftup和shiftdown问题的关键。
堆的子节点都要比父节点小

ShiftUp

上浮操作呢在逻辑上要比下沉操作简单,所以先来讨论上浮操作。
ShiftUp为上浮操作,插入操作主要是由ShiftUp完成,新增接点在尾部插入,然后将count+1,用上浮操作对数字进行上浮,让插入的数字上浮到应该在这个堆中所处的位置。传入count为形参k,所在的位置不断上浮,当母节点(k/2)上的元素值小于子元素(k)则发生一次交换,来维持这个堆.。
具体代码如下

    public void insert(int val) {

        arr[count + 1] = val;

        shiftUp(++count);

    }
    public void shiftUp(int k) {

        while (k >= 0 && arr[k] > arr[k / 2]) {
            swap(k / 2, k);
            k /= 2;
        }

    }

ShiftDown操作

shiftdown操作有点复杂,主要是子节点选择方面,我们可以先将k*2设成j,再将左右子节点进行比较,我们选取较大的那个,与k的元素进行比较,取最小者进行交换操作。代码如下

  public void shiftDown(int k) {

        while (2 * k <= count) {
            int j = k * 2;
            if (j + 1 <= count && arr[j + 1] > arr[j]) {
                j += 1;
            }
            if (arr[j] > arr[k]) {
                swap(j, k);
                k = j;
            } else {
                break;
            }

        }


    }

堆排序

堆排序也是一个比较高效的排序算法,主要是在于我们只需要去最大的0位元素,然后将它做类似弹出(POP)的操作即可实现,首先取出第一位元素,将最后一位(k)元素与第一位(0)元素进行交换,对有效个数进行-1操作(count–),这时,k位元素为最大值,并且已被丢弃,而第一位为最小,执行shiftdown让此时的第一位元素下沉维护堆的性质。

 public int extractMax() {
        int ret = arr[0];
        swap(0, count);
        count--;
        shiftDown(0);
        return ret;

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值