• 看正月点灯笼老师的笔记—堆排序


    先上代码

    void swap(int a[], int i, int j)
    {
    	int t = a[i];
    	a[i] = a[j];
    	a[j] = t;
    }
    void heapify(int tree[], int n, int i)   // 从第 i 个 开始做 heapify
    {
    	if (i >= n)
    		return;
    	int c1 = 2 * i + 1;
    	int c2 = 2 * i + 2;
    
    	int max = i;
    	if (c1 < n&&tree[c1] > tree[max])
    		max = c1;
    	if (c2 < n&&tree[c2] > tree[max])
    		max = c2;
    	if (max != i)
    	{
    		swap(tree, max, i);
    		heapify(tree, n, max);
    	}
    }
    void build_heap(int tree[], int n)
    {
    	int last_node = n - 1;
    	int parent = (last_node - 1) / 2;
    
    	for (int i = parent; i >= 0; i--)
    		heapify(tree, n, i);
    }
    void heap_sort(int tree[], int n)
    {
    	build_heap(tree, n);
    
    	for (int i = n - 1; i >= 0; i--)
    	{
    		swap(tree, i, 0);
    		heapify(tree, i, 0);
    	}
    }
    int main(void)
    {
    #define N 1086
    	int a[N] = { 0 };
    	int n;
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++)
    	{
    		scanf("%d", &a[i]);
    	}
    
    	heap_sort(a, n);
    
    	for (int i = 0; i < n; i++)
    	{
    		printf("%d ", a[i]);
    	}puts("");
    
    	system("pause");
    	return 0;
    }
    

    一,先看 heapify 函数

    heapify 是构造完全二叉树需要用到的特定的操作,所以单独列出一个函数:

    二叉树数据间是没有任何关系的,而这个函数是把二叉树的父与子中父找出来,并移到父的位置,

    并用递归调用 维护交换后,被破环的子节点与其子结点的关系,直到越界

    二,build_heap

    这个是用来构造 完全二叉树

    这里要区分一点是:

    ① heapify 是对一个父结点与两结点进行排序。递归调用之后,它所走的路程是 从结点开始向下找最大值,

    所以必须存在比父结点大的子结点,它才能继续往下走

    所以 heapify第一个结点是不能构造 heap 的。

    ② 所以要用到 build_heap 函数:

    先找到最后一个父结点,在从父结点开始调用 heapify ,从下面往上构造。

    三,heap_sort

    先明白一下 完全二叉树并不是完全排好序,但第一个结点一定是所有元素中最大的。

    所以,就可以利用这点去排序

    1,既然已经是最大的,那么就把这个数提走,剩下的在 heapify

    2, 但是这样两个问题,要把最大值放哪?拿走之后,原位置上的元素怎么处理掉?

    3,紧接着,我们就知道必须用一个较小值取替换父结点,不然无法 heapify 了,也就无法找到剩下的最大值

    那么我们就可以把最后一个结点(它不一定是最小的,但它足够小了)与父节点交换值,

    这样就形成了一个效果,最大的在最后面,已经排好了一个

    4,然后就把剩下的做一次 heapify ,为什么不是 build_heap,因为它只破坏了父节点,其他完全没动,这就是 heapify 的功能,

    这样 heapify 之后就找到剩下的最大值了,

    注意每次 heapify  的时候,它的作用范围必须减一,这样才不会波及排好序的元素,

    over ! !  感谢观看!!

    == ================================ ==

    寄扬州韩绰判官  杜牧 唐

    青山隐隐水迢迢,秋尽江南草未凋。

    二十四桥明月夜,玉人何处教吹箫。

     

     

  • 相关阅读:
    Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)
    MySQL 数据备份与还原
    java实现时钟方法汇总
    java实现二叉树demo
    java实现心型、99乘法demo
    显示本月日历demo
    打开图片并显示在面板上demo
    ArraySort--冒泡排序、选择排序、插入排序工具类demo
    类的实例化顺序
    StringsUtil字符串工具类---灵活截取
  • 原文地址:https://www.cnblogs.com/asdfknjhu/p/12410671.html
Copyright © 2020-2023  润新知