ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

堆排序(两种实现思路)

2021-06-12 18:01:22  阅读:174  来源: 互联网

标签:两种 int void 堆排序 length static 数组 思路 data


相信有了最大堆的实现基础,我们就可以开始考虑利用最大堆的特性,实现排序的功能。

1、第一种思路:需要开辟新的空间。
我们堆传入的数组,首先需要整理成最大堆的形式。我们循环遍历每个数组的元素,然后利用堆的add方法,最终把一个数组实现成最大堆的形式。然后我们开始循环遍历最大堆,每次都使用最大堆的取出最大元素的方法,不断的放入传入的数组里。循环结束后,我们的数组则是按照从大到小的顺序。最后再倒序一下数组,就完成了堆排序。

2、第二种思路:不需要开辟额外的空间,进行原地的排序。
这种方法我们称为Heapify。
第一步:我们首先堆数组实现原地的进行最大堆的实现。也就是从最后一个非叶子节点开始,从后往前,不断进行节点的下沉操作。如何获取最后一个非叶节点的位置呢,其实也就是最后一个索引的(index-2)/2 的计算。
第二步,我们循环地把索引为0 的位置和末尾位置的元素进行交换,这样我们便把最大值放在了最后。然后最元素为0的位置就行下沉操作,其中注意,我们下沉的时候,数组的大小需要减1,也就是不包含末尾已经排好序的元素。

具体的代码实现:

public class HeapSort {

    private HeapSort() {
    }

// 第一种方法
    public static <E extends Comparable<E>> void sort(E[] data) {
        MaxHeap<E> maxHeap = new MaxHeap<>();
        for (E e : data) {
            maxHeap.add(e);
        }

        for (int i = data.length - 1; i >= 0; i--) {
            data[i] = maxHeap.extractmax();
        }
    }

// 第二种方法
    public static <E extends Comparable<E>> void sort2(E[] data) {
        if (data.length <= 1) return;
        // 需要进行heapify
        // 从最后一个非叶子结点进行下沉操作
        // (data.length-2)/2
        for (int i = (data.length - 2) / 2; i >= 0; i--) {
            shifDown(data, i, data.length);
        }
        for (int i = data.length - 1; i >= 0; i--) {
            swap(data, 0, i);
            shifDown(data, 0, data.length - i);
        }
    }

    private static <E extends Comparable<E>> void shifDown(E[] data, int k, int n) {
        // 下沉操作,是个循环的操作
        // 下沉的节点大于0 并且左孩子也有
        while ( (2 * k) + 1 < n) {
            int j = (2 * k) + 1;
            if (j + 1 < n && data[j].compareTo(data[j + 1]) < 0) {
                j = j + 1;
            }
            if (data[k].compareTo(data[j]) >= 0) {
                break;
            }
            swap(data, k, j);
            k = j;
        }
    }

    private static <E extends Comparable<E>> void swap(E[] data, int k, int j) {
        E t = data[k];
        data[j] = data[k];
        data[k] = t;
    }

标签:两种,int,void,堆排序,length,static,数组,思路,data
来源: https://blog.csdn.net/xiaocl123/article/details/117851502

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有