算法-堆排序

大顶堆:在完全二叉树的基础上,每个结点的值都大于或等于其左右孩子结点的值

p在主函数中通过循环p-- 指针向前走

 public static void main(String[] args) {
        int[] arr = {8,7,3,5,4,9,1,3};
        for (int p = arr.length-1;p>=0;p--){
            adjustHeap(arr,p,arr.length);
        }
    }

在第5次循环的时候 终于找到了儿子节点

但此时temp=5 >3,不满足交换的条件,所以继续往前走

 

此时 temp=3 <5(其左子节点),所以进行交换

此时变成了

public static void adjustHeap(int[] arr,int parent,int length){
          // 定义一下父节点的值
        int temp = arr[parent];
        //定义左孩子
        int lChild = 2 * parent +1;
		//循环是为了检查交换后的儿子节点有没有儿子节点,如果有再次比较大小
        while (lChild <length){
            // 定义右孩子
            int rChild = lChild + 1;
            // 找打左右孩子当中最大的是谁
            if (rChild <length && arr[lChild] <arr[rChild]){
                lChild++;
            }

            if (temp >= arr[lChild]){
                break;
            }

            // 把子节点的值赋值到父节点的位置
            arr[parent] = arr[lChild];

            parent = lChild;
            lChild = 2 * lChild+1;
        }
        arr[parent] = temp;
    }

其中 while循环是为了检查交换后的儿子节点有没有儿子节点,如果有再次比较大小

 while (lChild <length){
            // 定义右孩子
            int rChild = lChild + 1;
            // 找打左右孩子当中最大的是谁
            if (rChild <length && arr[lChild] <arr[rChild]){
                lChild++;
            }

            if (temp >= arr[lChild]){
                break;
            }

            // 把子节点的值赋值到父节点的位置
            arr[parent] = arr[lChild];

            parent = lChild;
            lChild = 2 * lChild+1;
        }

此时parent的指针指到了其子节点上面,其子节点的的指针指到了变换之后子节点的子节点上面

这个时候由于变换之后的parent上没有子节点

所以 不满足

  while (lChild <length)

的循环条件,所以结束while循环 

执行

 arr[parent] = temp;

这一步的完成标志着 交换完成 

结束此次for循环

 

继续执行for循环

 

 

依然是父节点上的值比子节点大,不进行交换,继续向前走

 

 此时一个大顶堆产生,最大的值产生了出来

要进行堆排序,需要产生数组长度个大顶堆

public class HeapSort {
    public static void main(String[] args) {
        int[] arr = {8,7,3,5,4,9,1,3};
        int l=arr.length;
        int[] sort =new int[arr.length];
        for(int i=sort.length-1;i>=0;i--) {
          for (int p = l-1;p>=0;p--){
            adjustHeap(arr,p,l);  
          }
        sort[i]=arr[0];
        arr[0]=arr[l-1];
        l--;
       }
        System.out.println(Arrays.toString(sort));
    }

在原来产生大顶堆的for循环外面再套一层for循环

内部的for循环完毕产生一个大顶堆,也就是一个当前最大值,将这个最大值放在新数组的最后一位

 sort[i]=arr[0];

并将arr数组的首位拿掉,将末位放在首位,也就意味之数组长度减一

  arr[0]=arr[l-1];
        l--;

通过两层循环,得到了一个从大到小排序的数组

这就是堆排序

源代码部分:

import java.util.Arrays;

public class HeapSort {
    public static void main(String[] args) {
        int[] arr = {8,7,3,5,4,9,1,3};
        int l=arr.length;
        int[] sort =new int[arr.length];
        for(int i=sort.length-1;i>=0;i--) {
          for (int p = l-1;p>=0;p--){
            adjustHeap(arr,p,l);  
          }
        sort[i]=arr[0];
        arr[0]=arr[l-1];
        l--;
       }
        System.out.println(Arrays.toString(sort));
    }

    public static void adjustHeap(int[] arr,int parent,int length){
          // 定义一下父节点的值
        int temp = arr[parent];
        //定义左孩子
        int lChild = 2 * parent +1;
		//循环是为了检查交换后的儿子节点有没有儿子节点,如果有再次比较大小
        while (lChild <length){
            // 定义右孩子
            int rChild = lChild + 1;
            // 找打左右孩子当中最大的是谁
            if (rChild <length && arr[lChild] <arr[rChild]){
                lChild++;
            }

            if (temp >= arr[lChild]){
                break;
            }

            // 把子节点的值赋值到父节点的位置
            arr[parent] = arr[lChild];

            parent = lChild;
            lChild = 2 * lChild+1;
        }
        arr[parent] = temp;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值