zoukankan      html  css  js  c++  java
  • 堆排序(heapsort)

    堆排序的运行时间为Θ(nlgn),它是一种原地排序算法:在任何时候,数组中只有常数个元素存储在输入数组以外;

    对数据结构是一种数组对象,它可以被视为一棵完全二叉树。树中得每个结点与数组中存放该结点值的那个元素对应。

    树的每一层都是填满的,最后一层可能除外,表示堆的数组A是一个具有两个属性的对象:length[A]是数组中的元素

    个数,heap-size[A]是存放A中的堆元素个数。

    给定某个结点的下标 i , 其父结点PARENT(i),左儿子LEFT(i)和右儿子RIGHT(i)的下标可以计算出来:

    PARENT(i)

      return i/2

    LEFT(i)

      return 2 * i

    RIGHT(i)

      return 2 * i + 1

    最大堆是指除了根以外的每个结点 i,有 A[PARENT(i)] >= A[i]

    最小堆是指除了根以外的每个结点 i,有 A[PARENT(i)] <= A[i]

    在堆排序算法中使用的是最大堆。

    保持堆的性质  MAX- HEAPIFY 过程:

    MAX-HEAPIFY(A, i)
      l ← LEFT(i)
      r ← RIGHT(i)
      if l <= heap-size[A] and A[l] > A[i]
        then largest ← l
        else largest ← i
      if r <= heap-size[A] and A[r] > A[largest]
        then largest ← r
      if largest != i
    
        then exchange A[i] ↔ A[largest]
          MAX-HEAPIFY(A, largest)

    BUILD-MAX-HEAP过程:

    BUILD-MAX-HEAP(A)
      heap-size(A) ← length[A]
      for i ← length[A]/2 downto 1
        do MAX-HEAPIFY(A, i)

    堆排序算法:

    HEAPSORT(A)
      BUILD-MAX-HEAP(A)
      for i ← length[A] downto 2
        do exchange A[1] ↔ A[i]
          heap-size[A] ← heap-size[A] - 1
          MAX-HEAPIFY(A, 1)

    Java实现

        public void heapSort(int[] a)
        {
            int heapSize = a.length;
            buildMaxHeap(a);
            for (int i = a.length - 1; i > 0; i--)
            {
                swap(a, 0, i);
                maxHeapify(a, 0, --heapSize);
            }
        }
        
        private void buildMaxHeap(int[] a)
        {
            for (int i = a.length / 2; i >= 0; i--)
            {
                maxHeapify(a, i, a.length);
            }
        }
        
        private void maxHeapify(int[] a, int i, int heapSize)
        {
            int largest = 0;
            int l = 2 * i + 1;
            int r = 2 * i + 2;
            if (l < heapSize && a[l] > a[i])
            {
                largest = l;
            }
            else
            {
                largest = i;
            }
            if (r < heapSize && a[r] > a[largest])
            {
                largest = r;
            }
            if (largest != i)
            {
                swap(a, i, largest);
                maxHeapify(a, largest, heapSize);
            }
        }
        
        private void swap(int[] data, int src, int des)
        {
            int tmp = data[des];
            data[des] = data[src];
            data[src] = tmp;
        }

    用Java实现伪码需要注意

    1.数组的下标:

    • 大于1还是大于0,等等
    • 因为Java的数组下标是从0开始,与伪码对应的结点 i 左孩子右孩子的下标分别是2*1+1, 2*i+2.

    2.maxHeapify需要一参数heapSize是因为在heapSort交换后,要从堆中去掉此元素结点(此时去掉的元素结点就是堆中的最大结点)

    3.堆排序是分3个过程来完成,在最后验证堆排序的实现是否正确,先测试验证maxHeapify正确,然后是建堆buildMaxHeap正确,最后验证

    堆排序是否正确。否则一开始就验证堆排序,出了问题就不知道到底是哪个过程出错。

  • 相关阅读:
    Scrapy snippets
    HttpClient4的cookie rejected问题,以及如何消除该warning输出
    简单的python smtp发邮件代码
    FTP服务器:Proftpd
    “当HTML5来敲门”专题沙龙杂记
    Titanium Mobile 1.6版本发布
    给同学们分享一些面试经验
    用CSS3实现动画进度条
    3天内构建Facebook Web应用的经验之谈
    仅用CSS创建立体旋转幻灯片
  • 原文地址:https://www.cnblogs.com/zhuqiang/p/2485943.html
Copyright © 2011-2022 走看看