Heap sort

heap definition

1.堆是完全二叉树

2.所有父节点一定要大于子节点(大顶堆)

1.heapify

在这里插入图片描述

/**
     *递归写法:二叉树的后序遍历
     * @param tree :存储堆的数组
     * @param n : 数组的长度
     * @param i : 数组索引,表示此时的节点:表示对哪一个点进行heapify操作
     */
    public void heapify(int[] tree , int n , int i){

        if(i >= n)  return;//递归终止条件

        int c1 = 2 * i + 1;//此时节点的左子节点
        int c2 = 2 * i + 2;//此时节点的右子节点
        int max = i;//假设刚开始最大值节点是该节点

        //看看最大值是不是左子节点
        if(c1 < n && tree[c1] > tree[max]){
            max = c1;
        }

        //看看最大值是不是右子节点
        if(c2 < n && tree[c2] > tree[max]){
            max = c2;
        }

        //如果最大值节点是其左子节点或者右子节点,进行swap
        //如果最大值max就是跳出循环
        if(max != i){
            swap(tree,max,i);//max指向的是i的左子结点或者右子结点
            //向下递归操作i的左子结点或者右子结点
            heapify(tree,n,max);
        }
    }

	private void swap(int[] tree, int i, int j) {
        int tmp = tree[i];
        tree[i] = tree[j];
        tree[j] = tmp;
    }
    

2. buildHeap

private void buildHeap(int[] tree , int n){
        int lastNode = n - 1;//最后一个叶子结点
        int parent = (lastNode - 1) / 2;//最后一个叶子结点的父亲结点
        for(int i = parent ; i >= 0 ; i--){
            heapify(tree,n,i);
        }
    }

3.heap sort

private void heapSort(int[] tree , int n){
        //建堆
        buildHeap(tree,n);
        //堆排序
        //每次都是:
        //1.将堆的最后一个元素和堆顶元素进行swap(堆顶元素是max值)
        //2.删除数组的最后一个元素,可以不用真正的去删除它,用i表示
        //3.交换完后对堆顶元素heapify操作
        for(int i = n - 1 ; i >= 0 ; i--){
            swap(tree,i,0);
            //一开始的写法:heapify(tree,n,0);
            //只要让n改成i,i是不断减少的不用进行最后一个元素的砍断操作
            heapify(tree,i,0);
        }

    }

4.summary

import java.util.Arrays;
import java.util.HashMap;
import java.util.function.Predicate;

/**
 * @author zzyuan
 * @date 2021/11/20 - 14:55
 */
public class Demo {

    /**
     *
     * @param tree :存储堆的数组
     * @param n : 数组的长度,节点的个数
     * @param i : 数组索引,表示此时的节点
     */
    public void heapify(int[] tree , int n , int i){

        if(i >= n)  return;//递归终止条件

        int c1 = 2 * i + 1;//此时的节点的左子节点
        int c2 = 2 * i + 2;//此时的节点的右子节点
        int max = i;//假设刚开始最大值节点是该节点

        //看看最大值是不是左子节点
        if(c1 < n && tree[c1] >tree[max]){
            max = c1;
        }

        //看看最大值是不是右子节点
        if(c2 < n && tree[c2] > tree[max]){
            max = c2;
        }

        //如果最大值节点是其左子节点或者右子节点,进行swap
        if(max != i){
            swap(tree,max,i);
            //向下递归操作
            heapify(tree,n,max);
        }
    }

    private void buildHeap(int[] tree , int n){
        int lastNode = n - 1;
        int parent = (lastNode - 1) / 2;
        for(int i = parent ; i >= 0 ; i--){
            heapify(tree,n,i);
        }
    }

    private void heapSort(int[] tree , int n){
        //建堆
        buildHeap(tree,n);
        //堆排序
        //每次都是:
        //1.将堆的最后一个元素和堆顶元素进行swap(堆顶元素是max值)
        //2.删除数组的最后一个元素,可以不用真正的去删除它,用i表示
        //3.交换完后对堆顶元素heapify操作
        for(int i = n - 1 ; i >= 0 ; i--){
            swap(tree,i,0);
            heapify(tree,i,0);
        }

    }

    private void swap(int[] tree, int i, int j) {
        int tmp = tree[i];
        tree[i] = tree[j];
        tree[j] = tmp;
    }

    public static void main(String[] args) {
        int[] tree = {2,5,3,1,10,4};
        int n = 6;
        Demo demo = new Demo();
//        demo.buildHeap(tree,tree.length);
        demo.heapSort(tree,n);
        System.out.println(Arrays.toString(tree));


    }


}

在这里插入图片描述

这up主的堆排序讲的很好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值