美文网首页
(311)排序-堆排序

(311)排序-堆排序

作者: 林湾村龙猫 | 来源:发表于2016-01-21 01:20 被阅读125次

概述

堆常用来实现优先队列,在这种队列中,待删除的元素为优先级最高(最低)的那个。在任何时候,任意优先元素都是可以插入到队列中去的,是计算机科学中一类特殊的数据结构的统称
  堆的定义:最大(最小)堆是一棵每一个节点的键值都不小于(大于)其孩子(如果存在)的键值的树。大顶堆是一棵完全二叉树,同时也是一棵最大树。小顶堆是一棵完全完全二叉树,同时也是一棵最小树。注意:

  • 堆中任一子树亦是堆。
  • 以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义k叉堆。
  • 左右子节点不大于(不小于)父节点。

堆排序是根据堆中的根节点是最大或最小值来排序的。

理论

http://blog.csdn.net/morewindows/article/details/6709644
http://blog.csdn.net/wypblog/article/details/8076324
http://blog.csdn.net/v_july_v/article/details/6198644

动画

堆排序动画1
堆排序动画2

代码(PHP)

1.堆定义极其排序方法

class Heap{
    protected $tree = array();//数组存储的完全二叉树
    protected $type= 'max';//max-最大堆,min-最小堆

    public function __construct($arr=null,$type='max'){
        $this->initHeap($arr,$type);
    }

    //初始化数据堆
    public function initHeap($arr = null,$type='max'){
        if(empty($arr)){
            return;
        }
        $this->tree = $arr;
        $this->type = strtolower($type) == 'max'?'max':'min';
        $length = count($arr);
        for($i= (int)($length/2-1); $i>=0;$i--){
            $this->heapFix($i);
        }
    }

    //调整$i节点极其之后节点子树
    public function heapFix($i=0,&$tree=null){
        //完全二叉树,i节点的子节点为 2*i+1, 2*i+2(i从0开始)
        if(empty($tree)){
            $tree = &$this->tree;
        }
        $length = count($tree);
        $i_left = 2*$i+1;//左节点
        $i_right = $i_left+1;//右节点
        while($i_left <= $length-1){
            $temp = $i_left;
            if($this->type == 'max'){//大根堆
                if(!empty($tree[$i_right]) && $tree[$i_left]<$tree[$i_right]){
                    $temp = $i_right;
                }
                if($tree[$i] >= $tree[$temp]){
                    break;
                }
            }else{//小根堆
                if(!empty($tree[$i_right]) && $tree[$i_left] > $tree[$i_right]){
                    $temp = $i_right;
                }
                if($tree[$i] <= $tree[$temp]){
                    break;
                }
            }
            list($tree[$i],$tree[$temp])= array($tree[$temp],$tree[$i]);
            $i = $temp;
            $i_left = 2*$i+1;
            $i_right = $i_left+1;
        }
    }

    //堆排序
    public function heapSort(){
        $arr = array();
        $tree = $this->tree;
        while(!empty($tree)){
            //将根节点和最后一个节点交换,保存最后节点,删除最后节点,调整堆结构
            $length = count($tree);
            list($tree[0],$tree[$length-1]) = array($tree[$length-1],$tree[0]);
            $arr[] = $tree[$length-1];
            unset($tree[$length-1]);
            $this->heapFix(0,$tree);
        }
        return $arr;
    }
}

重建堆的基本思想-实际的操作:将最后一个数据的值赋给根结点,然后再从根结点开始进行一次从上向下的调整。调整时先在左右儿子结点中找最小(大)的,如果父结点比这个最小(大)的子结点还小说明不需要调整了,反之将父结点和它交换后再考虑后面的结点。相当于从根结点将一个数据的“下沉”过程。

2.调用

$item =array('2','1','4','3','8','6','5','-1','10','3','7','6','6');
var_dump(implode(',',$item));
$heap = new Heap($item,'min');
var_dump(implode(',',$heap->heapSort()));

结果


堆排序

相关文章

  • (311)排序-堆排序

    概述 堆常用来实现优先队列,在这种队列中,待删除的元素为优先级最高(最低)的那个。在任何时候,任意优先元素都是可以...

  • 堆排序

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

  • 堆排序---基础篇

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

  • 堆和堆排序

    最小K个数 堆排序 堆排序

  • JS实现堆排序

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

  • 堆排序

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

  • iOS算法总结-堆排序

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

  • 3.2-选择排序-堆排序

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

  • php-归并排序、快速排序、堆排序

    归并排序、快速排序、堆排序 时间复杂度 O(nlogn) 归并排序 快速排序(快排) 堆排序

  • [go语言 排序算法]

    快速排序 堆排序

网友评论

      本文标题:(311)排序-堆排序

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