堆排序算法

堆中定义以下几种操作:

  • 最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
  • 创建最大堆(Build_Max_Heap):将堆所有数据重新排序
  • 堆排序(HeapSort):卸载位在第一个数据的根节点,并做最大堆调整的递归运算

堆排序算法的基本特性:

时间复杂度:O(N * logN)

堆排序为不稳定排序,不适合记录较少的排序。

测试结果:

数组里有10000个随机数, 执行500次后花费的毫秒数
最大毫秒数为17
最小毫秒数为8
平均毫秒数为10

示例代码:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>堆排序算法</title>
</head>
<body>
<script>
var count = 10000,
    num = testCount = 500,
    i,
    exeCount,
    exeTimeArr = [],
    
     // 最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
    makeMax = function(a, pIndex, size){
        var largest = pIndex,
            lIndex= 2 * pIndex + 1,
            rIndex = lIndex + 1;

        if(a[pIndex] < a[lIndex] && lIndex < size){
            largest = lIndex;
        }

        if(a[largest] < a[rIndex] && rIndex < size){
            largest = rIndex;
        }

        if(largest != pIndex){
            a[pIndex] = [ a[largest], a[largest] = a[pIndex] ] [0]; // 交换顶、左(右)节点2个数
            a = makeMax(a, largest, size);
        }

        return a;
    },

    heapSort = function(a){
       
        // 创建最大堆(Build_Max_Heap):将堆所有数据重新排序
        for(var len = a.length, i = Math.floor( (len - 2) / 2 ); i >= 0; i--){
            a = makeMax(a, i, len);
        }

        // 头尾交换并确保最大堆成立
        for(i = len - 1; i >= 0; i--){
            a[0] = [ a[i], a[i] = a[0] ] [0];        // 头尾交换
            a = makeMax(a, 0, i); //确保最大堆成立
        }
 
        return  a;
 
    };

var body = document.getElementsByTagName('body')[0];
var log = function(s){

    var p = document.createElement('p');
    var ps = document.getElementsByTagName('p');

    p.innerHTML = s;

    ps.length ?
        body.insertBefore(p, ps[0]) :
        body.appendChild(p);

    //document.write(s + '<br />'); 破坏文档结构
    //firefox下使用console.log并开启firebug会影响执行
}

function exeTest( callback ){

    function test(){
        var cost,
            startTime,
            arr = [];

        testCount--;

        // 构建随机数组
        for(i=0;i<count;i++){
            arr.push( Math.round(Math.random() * count) ); // 0 - count
        }

        startTime = + new Date();
        arr = heapSort(arr);
        exeTimeArr.push(cost = new Date() - startTime); //花费的毫秒数

        log('本次测试花费 '+ cost +' 毫秒, 还剩 '+ testCount +' 次测试');

        if(testCount == 0 && typeof callback == 'function'){

            callback();

        }else{

            // 预防浏览器挂起
            setTimeout(test, 10);
        }
    }

    test();
}

function callback(){
    var sum = 0;
    var result = '数组里有'+ count +'个随机数, 执行'+ num +'次后花费的毫秒数' + '<br />' +
                      '最大毫秒数为' + Math.max.apply(null, exeTimeArr) + '<br />' +
                      '最小毫秒数为' + Math.min.apply(null, exeTimeArr) + '<br />';

    exeTimeArr.forEach(function(value) {
        sum += value;
    })

    result += '平均毫秒数为' + Math.round( sum / num ) ;

    log(result);
}

// 执行100次测试完成时间
exeTest(callback);

</script>
</body>
</html>



你可能感兴趣的:(堆排序算法)