tuotuo刷题-堆排序

大顶堆建堆方式

· 第一种

将所有待排序元素输入后开始排序

//需要实现down的调整,即将某个位置是元素向下调整到其应该到的位置上
//调整顺序应该从倒数第二列开始,即最后一个元素的父节点开始
    void adjustDown(vector<int>& a, int n, int parent){
        int child = parent * 2 + 1;
        if (child < n)
            //当 孩子的下标 超出 数组的范围,则说明不存在
            {
                //1.选出左右孩子中,较小的一个
                //child -- 左孩子下标;child+1 -- 右孩子下标
                if (child + 1 < n && a[child + 1] < a[child])
                {
                    //想象的时候:默认左孩子是比右孩子小
                    //如果大的话,child就走到右孩子下标处
                    child++;
                }
        
                //2.交换
                if (a[child] < a[parent])
                {
                    swap(a[child], a[parent]);
                    parent = child;
                    adjustDown(a, n, child);
                }
            }
    }

下面是建堆代码:

	int n = arr.size();
    for(int i = (n - 1) / 2; i >= 0 ; i--){
          adjustDown(arr, n,i);
      }

· 第二种

将每一个元素放在最末尾,然后往上up

    void adjustUp(vector<int> & a, int child){
        int parent = (child - 1) / 2;
        if(parent >= 0)
        {
            if(a[parent] > a[child]){
                swap(a[parent], a[child]);
                adjustUp(a, parent);
            }
        }
    }

构建代码:

        int n = arr.size(); //arr里面是无序的
        vector<int> temp;
        for(int i = 0; i < n; i++){
            temp.push_back(arr[i]);
            adjustUp(temp, i);
        }

排序输出:

堆排序的数组中,并不能直接有序输出,而是要先输出第一个,然后把第一个和最后一个元素交换,让交换了以后的堆头元素down到合适的位置。这个方式每次只能输出一个元素,但能保证是目前数组中最大的或者是目前数组中最小的。

代码:

  for(int i = 0; i < n; i ++)
  {
      cout << temp[0] <<' ';
      swap(temp[0], temp[temp.size() - 1]);
      temp.pop_back();
      adjustDown(temp, temp.size(), 0);
  }   

例题:最小的前k个数

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值