Java进行堆排序

堆的基本概念

堆就是由完全二叉树构成的,而完全二叉树又包括满二叉树或者从左往右依次填充叶结点的树,即要么没有叶节点,如果只有一个叶节点必然是左叶结点。

堆结点的关系

父节点下标为i,则左孩子的坐标为2i+1,右孩子的坐标为2i+2.注下标从0开始

堆排序的步骤

第一步:
根据给出的数据建立堆,本题是升序排列,所以建立大根堆(如果降序排列则建立小根堆,至于为何,看完剩下的步骤就知道了)

    public static void heapInsert(int[]arr,int index){
        while (arr[(index-1)/2]<arr[index]){
        //每个元素寻找自己的父节点,然后与父节点的值进行比较
            swap(arr,index,(index-1)/2);
       //交换后其余大小关系又会发生改变,所以要继续向上比较,判断是否要继续交换 
            index=(index-1)/2;
        }
         }

第二步:
1:将所有数据进行大根堆创建完成后(元素大小为size),根节点就是所有元素中的最大值,此时将根节点与最后一个元素进行交换位置,size–,此时最末尾元素就是我们需要的最大的元素。(每次得到一个值,所以我们要对堆进行size次处理)
2:由于最大的元素与最末尾元素交换了位置,此时大根堆的结构遭到破坏,我们就需要对大根堆进行调整,使它满足大根堆的结构

如何对结构被破坏的大根堆进行调整?

      public static void heapify(int[]arr,int index,int size){
        int left=2*index+1;
        while (left<size) {
            int larget = (left + 1 < size && arr[left] < arr[left + 1]) ? left + 1 : left;
            larget=arr[larget]>arr[index]?larget:index;
            if (larget==index)
                break;
            swap(arr,larget,index);
            index=larget;
            left=index*2+1;
        }
    }

1:index是交换完位置之后根节点的位置,我们首先要与size比较,判断该结点是否有左右孩子,然后找到左右结点中的最大值,如果交换后的根节点就是最大值,即larget==size,则break,否则交换index和larget的位置,然后继续进行往下判断。

整体代码:

package chap1;

import java.util.Arrays;

/**
 * @author your_tt
 * @date 2021年05月28日16:11
 */
public class OwnHeapSort {
    public static void HeapSort(int[] arr){
        if (arr.length<2 ||arr==null){
            return;
        }

        for (int index=0;index<arr.length;index++){
            heapInsert(arr,index);
        }
        int size=arr.length;
        swap(arr,0,--size);
        while (size>0){
            heapify(arr,0,size);
            swap(arr,0,--size);
        }
    }

    public static void heapInsert(int[]arr,int index){
        while (arr[(index-1)/2]<arr[index]){
            swap(arr,index,(index-1)/2);
            index=(index-1)/2; 
        }
    }

    public static void heapify(int[]arr,int index,int size){
        int left=2*index+1;
        while (left<size) {
            int larget = (left + 1 < size && arr[left] < arr[left + 1]) ? left + 1 : left;
            larget=arr[larget]>arr[index]?larget:index;
            if (larget==index)
                break;
            swap(arr,larget,index);
            index=larget;
            left=index*2+1;
        }
    }
    //交换
    public static void swap(int arr[],int i,int j){
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    public static void main(String[] args) {
        int[] test={9,8,7,6,5,4,3,2,1,88};
        HeapSort(test);
        System.out.println(Arrays.toString(test));
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值