• 二叉堆排序


    二叉堆的内容详见上篇http://www.cnblogs.com/deltadeblog/p/8576488.html

    可以利用二叉堆对数组排序,主要包含两步:将原始数组重新组织使之成为二叉堆;数组的第一个元素为最大或最小,取出后对数组使用sink()函数保持堆有序,依次进行。

    堆的构造

    将一个包含N个元素的数组构造成二叉堆。方法1是使用swim()函数从左到右遍历数组的每一个元素,

    该方法的复杂度为O(NlogN)。

    另一个方法是使用sink()函数从右至左遍历数组元素,由于叶子结点下没有其他节点,所以sink()函数可以从分支节点开始遍历,不要遍历每个数组元素。sink(i) ,i=N/2; i>=1; i--

    实现代码如下:

    for (int i=N/2; i>=1; i--) sink(a, N, i);

    算法复杂度:少于2N次比较及N次交换。

    排序

    将数组构造为堆,则数组的第一个元素即是最大(或最小),将该元素与数组最后一个元素交换。

    对余下的元素(0 - N-2)使用sink()函数继续进行堆构造并与最后一个元素交换。

    整个算法的代码如下:

    import java.util.Arrays;
    
    public class StackSort {
    
        private static boolean less(int[] a, int i, int j) {
            return a[i-1]<a[j-1];
        }
    
        private static void exch(int[] a, int i, int j) {
            int temp = a[i-1];
            a[i-1] = a[j-1];
            a[j-1] = temp;
        }
    
        public static void sink(int[] a, int N, int i) {
    
            while (2*i <= N) {
    
                int j = 2*i;
                while(j<N && less(a, j, j+1)) j++;
                if (!less(a, i, j)) break;
                exch(a, i, j);
    
                i = j;
            }
        }
    
        public static void sort(int[] a) {
    
            int N = a.length;
            // 使用sink()对数组a堆排序
            // 使之成为二叉堆
            for (int i=N/2; i>=1; i--) sink(a, N, i);
            // 对数组a排序
            for (int i=N; i>1; i--) {
                exch(a, 1, i);
                sink(a, i-1, 1);
            }
        }
    
        public static void main(String[] args) {
    
            int[] a = {8,3,7,10,9,12,6};
            sort(a);
            System.out.println(Arrays.toString(a));
        }
    }

    算法复杂度:

  • 相关阅读:
    PHP学习当中遗漏的知识点
    sql必知必会(第四版) 学习笔记
    servlet 笔记
    sql server 快捷键
    233
    第 四 课 数据类型
    第三课 go语言基础语法
    第二课 go语言的结构
    第 1 课 Go 简介
    linux 学习 查看文件占用空间大小
  • 原文地址:https://www.cnblogs.com/deltadeblog/p/8592774.html
Copyright © 2020-2023  润新知