• 《算法导论》第6章 堆排序 (1)最大堆与堆排序



    6.1 堆

    “堆”这个词最初是在堆排序中提出的,但后来就逐渐指“废料收集存储区”,像Lisp和Java中提供的那样。

    (二叉)堆是一种数组对象,可以被视为一棵完全二叉树。
    length[A]是数组中的元素个数,heap-size[A]是存放在A中堆的元素个数。
    树的根是A[1]。

    堆的重要函数:
    max_heapify
    build_max_heap
    heapsort

    6.2 - 6.4 最大堆

    // 将LEFT和RIGHT定义为宏(避免小函数调用的开销)
    // 注意宏的定义要加上括号避免文本替换时运算符问题
    #include <stdio.h>
    #define LEFT(i)     (2 * (i))
    #define RIGHT(i) (2 * (i) + 1)

    // 交换堆中的结点 i 和 j
    void exchange(int A[], int i, int j)
    {
         int tmp = A[i];
         A[i] = A[j];
         A[j] = tmp;
    }

    // 自结点 i 向下保持最大堆性质。
    void max_heapify(int A[], int heapsize, int i)
    {
         int l, r, largest;
         l = LEFT(i);
         r = RIGHT(i);

         // 确定结点 i, l, r 中最大者
         if (l <= heapsize && A[l] > A[i])
              largest = l;
         else
              largest = i;
         if (r <= heapsize && A[r] > A[largest])
              largest = r;

         // 如果结点 i 不是最大者,将其与最大结点largest交换
         // 并递归处理结点largest
         if (largest != i) {
              exchange(A, i, largest);
              max_heapify(A, heapsize, largest);
         }    
    }

    // 建堆:自底向上,对所有非叶子结点[heapsize/2, 1]
    // 调用max_heapify构造出堆性质。
    void build_max_heap(int A[], int heapsize)
    {
         int i;
         for (i = heapsize / 2; i >= 1; i--)
              max_heapify(A, heapsize, i);
    }

    // 堆排序:首先建堆,将根结点(最大值)交换到堆尾,
    // 将堆大小减1,然后让根结点保持堆性质,
    // 因为第一步的交换破坏了堆性质。
    void heapsort(int A[], int heapsize)
    {
         build_max_heap(A, heapsize);
         int i;
         for (i = heapsize; i >= 2; i--) {
              exchange(A, 1, heapsize);
              heapsize -= 1;
              max_heapify(A, heapsize, 1);    
         }
    }

    // 按堆逻辑结构打印。
    void print(int A[], int length)
    {
         int i, j;
         for (i = 1, j = 1; i <= length; i++, j--) {
              if (j <= 0) {
                   printf("\n");
                   j = i;
              }
              printf("%d\t", A[i]);
         }
         printf("\n\n");
    }

    // 测试建堆和堆排序。
    int main(void)
    {
         int A[20] = { 0, 16, 4, 10, 14, 7, 9, 3, 2, 8, 1 };
         int heapsize = 10;

         build_max_heap(A, heapsize);
         print(A, heapsize);

         heapsort(A, heapsize);
         print(A, heapsize);

         return 1;
    }




  • 相关阅读:
    JavaBean的详细及引用
    动态页面,登陆,注册,留言 JSP
    简单登陆,注册的动态网页
    11.24作业3
    11.24作业2
    转: JAVA递归算法实例小结
    转: javascript实现全国城市三级联动菜单代码
    转: 我们为什么使用ORM?
    转:Ajax中的get和post两种请求方式的异同
    转: JSTL SQL标签库 使用
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157867.html
Copyright © 2020-2023  润新知