美文网首页
写了一个堆排序

写了一个堆排序

作者: xin激流勇进 | 来源:发表于2020-09-21 17:39 被阅读0次


堆是一颗完全二叉树
堆中节点不大于或者不小于其父节点

入堆:
直接放入堆内部数据结构的最后,通过shiftUp操作,
与其父节点进行比较,交换位置

出堆:
内部数据结构的第一个(最大或者最小元素)和最后一个元素交换
位置 移除最后一个元素并返回 然后对第一个元素进行shiftDown操作
与其左右子节点比较,找出子节点中最大或者最小的节点交换位置

heapify
对给定的集合构建成最大堆 通过从后往前遍历(n / 2) -1 个节点, 即所有
非叶子节点,进行shiftDown操作。

for (int i = (n >>> 1) - 1; i >= 0; i --) {
       shiftDown(data[i])
}

将第一个元素(最大)和最后一个元素进行交换 让后对前n-1个元素中的第一个
进行shiftDown操作,依次循环,最后完成堆排序

package cn.school;

import java.util.Arrays;

public class Heap {

    //    "原先18现在22"

    public static void main(String[] args) throws Exception {

        Heap main = new Heap();
        main.heapSort(new Integer[]{234, 14, 12, 34, 299, 111});
        
    }

    public <T extends Comparable<T>> void heapSort(T[] arr) {
        
        //heapify 将传入的数组变成最大堆 对所有非叶子节点进行shiftDown操作
        //从最后一个节点到第一个非叶子节点
        for (int i = (arr.length >>> 1) - 1; i >= 0; i--) {
            shiftDown(i, arr, arr.length);
        }

//        swap(arr, 0, arr.length - 1);
//        shiftDown(0, arr, arr.length - 1);
//        swap(arr, 0, arr.length - 2);
//        shiftDown(0, arr, arr.length - 2);
//      建成最大堆后,将第一个元素和最后一个元素进行交换 之后再对0 - n-1 元素中
//        的0索引进行shiftDown操作,依次往复,最终排好序
        int lastIndex = arr.length - 1;
        while (lastIndex > 0) {
            swap(arr, 0, lastIndex);
            shiftDown(0, arr, lastIndex);
            lastIndex --;
        }

        System.out.println(Arrays.toString(arr));

    }

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


    private <T extends Comparable<T>> void shiftDown(int i, T[] arr, int size) {
        
        //将左右子节点中最大的和自己进行交换
        while (leftChild(i) < size) {
            int j = leftChild(i);
            if (j + 1 < size && arr[j + 1].compareTo(arr[j]) > 0) {
                j++;
            }

            if (arr[i].compareTo(arr[j]) >= 0) {
                break;
            }

            T tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;

            i = j;
        }
    }

    private int leftChild(int i) {
        return i * 2 + 1;
    }

    private int rightChild(int i) {
        return i * 2 + 2;
    }


}

相关文章

  • 写了一个堆排序

    堆堆是一颗完全二叉树堆中节点不大于或者不小于其父节点 入堆:直接放入堆内部数据结构的最后,通过shiftUp操作,...

  • 堆排序

    写了一个堆排序代码,支持升序和降序 参考 https://blog.csdn.net/u013384984/art...

  • 堆排序

    目录 1.堆排序介绍 2.堆排序图文说明 3.堆排序的时间复杂度和稳定性 4.堆排序实现 堆排序介绍 堆排序(He...

  • 堆排序---基础篇

    本文主要介绍堆排序的一些基本过程和分析。 大纲 堆排序简介 堆排序代码实现 1. 堆排序简介 1.1 堆排序的存储...

  • 堆和堆排序

    最小K个数 堆排序 堆排序

  • JS实现堆排序

    原理 堆排序原理 实现 说明 堆排序对大文件很有效 堆排序是不稳定排序

  • iOS算法总结-堆排序

    iOS算法总结-堆排序 iOS算法总结-堆排序

  • 常见排序算法

    希尔排序,快速排序,堆排序,2路归并算法的c++简单实现 在 里面写了一个随机数列生成,可以快速验证算法的正确性 ...

  • 堆排序

    堆排序首先堆排序分为两个过程,建堆和调整堆,其中建堆过程中也要用到调整堆,堆排序本质上是一个选择排序,是一个不稳定...

  • 堆排序

    转载:图解排序算法(三)之堆排序 预备知识 堆排序 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选...

网友评论

      本文标题:写了一个堆排序

      本文链接:https://www.haomeiwen.com/subject/uetbyktx.html