堆排序

作者: 暑水 | 来源:发表于2019-08-08 16:52 被阅读0次

定义:

  • 堆是一颗完全二叉树;
  • 堆中的某个结点的值总是大于等于(最大堆)或小于等于(最小堆)其孩子结点的值。
  • 堆中每个结点的子树都是堆树。

数据结构:

C 语言
struct MaxHeap
{
    EType *heap; //存放数据的空间,下标从1开始存储数据,下标为0的作为工作空间,存储临时数据。
    int MaxSize; //MaxSize是存放数据元素空间的大小
    int HeapSize; //HeapSize是数据元素的个数
};
MaxHeap H;

初始化堆

  public static void MaxHeapInit(int[] array) {
        for(int i = array.length/2; i > 0; --i){
            array[0] = array[i];//堆值存储从1开始,使用array[0]暂存
            int child = 2*i;
            while(child < array.length){
                if (child < array.length - 1 && array[child] < array[child+1])
                    child++;
                if(array[0] > array[child])
                    break;
                array[child/2] = array[child];
                child = child*2;
            }
            array[child/2] = array[0];
        }
    }

最大堆中插入结点

  • 最大堆中插入节点,先在堆末尾插入该节点,然后按照堆的初始化过程将该节点放入到合适的位置。
C 语言源码
void MaxHeapInsert(MaxHeap &H, EType &x)
{
    if(H.HeapSize==H.MaxSize) return false;    
    int i=++H.HeapSize;
    while(i!=1&&x>H.heap[i/2]){
        H.heap[i]=H.heap[i/2];
        i/=2;
    }
    H.heap[i]=x;
    return true;
}

最大堆中删除结点

  • 将最大堆的最后一个节点放到根节点,然后删除最大值,然后再把新的根节点放到合适的位置

实战:

  • 堆排序的基本思想:
    利用大顶堆(或者小顶堆也行),将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将它移走(其实就是使其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次大值。如此反复执行,便能得到一个有序序列了。
升序排序使用大顶堆,降序排序使小顶堆;
public class Main {
    public static void main(String[] args) {
        int[] array = { 0, 20, 70, 30, 10, 60, 50, 30, 90, 100 };
        String aString = Arrays.toString(array);
        System.out.println("排序前   " + aString);
        heapSort(array);
        aString = Arrays.toString(array);
        System.out.println("排序后  " + aString);
    }

    public static void heapSort(int[] array) {
        for (int i = array.length / 2; i > 0; i--) { // 建堆
            heapAdjust(array, i, array.length - 1);
        }

        for (int i = array.length - 1; i > 1; i--) {
            swap(array, 1, i); //将最大值交换到最后
            heapAdjust(array, 1, i - 1);//将剩余数组更新堆
        }
    }

    public static void heapAdjust(int[] array, int small, int large) {
        int temp = array[small];
        for (int j = small * 2; j <= large; j = j * 2) {
            if (j < large && array[j] < array[j + 1]) {
                j++;
            }
            if (temp >= array[j])
                break;
            array[small] = array[j];
            small = j;
        }
        array[small] = temp;
    }

    public static void swap(int[] array, int small, int large) {
        int temp = array[small];
        array[small] = array[large];
        array[large] = temp;
    }
}

相关文章

  • 堆排序

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

  • 堆排序---基础篇

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

  • 堆和堆排序

    最小K个数 堆排序 堆排序

  • JS实现堆排序

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

  • iOS算法总结-堆排序

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

  • 堆排序

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

  • 排序

    原创 堆排序: 使用visit数组从本质出发获取大顶堆排序。

  • 堆排序

    堆排序

  • C++基础入门之模板堆排序(上):模板上的list的创造与操作

    整段源码链接C++的模板元堆排序 要点 组建数据结构list 组建对list的各种基本操作 堆排序中组建堆排序个个...

  • 3.2-选择排序-堆排序

    参考链接 选择排序:堆排序(Heap Sort) 白话经典算法系列之七 堆与堆排序 堆排序与快速排序,归并排序一样...

网友评论

      本文标题:堆排序

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