堆排序算法-JS

一、堆排序算法介绍

     堆是一种特殊的树形数据结构,其每个结点都有一个值,通常提到的堆都是指一棵完全二叉树,根结点的值小于(或大于)两个子结点的值,同时,根结点的两棵子树也分别是-个堆。堆排序是一种树形选择排序,在排序过程中,将R[...n]看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结 点和孩子结之间的内在关系来选择最小的元素。
   堆一般分为大顶堆和小顶堆两种不同的类型。对于给定n个记录的序列(r(1), r(2), ... r(n)),当且仅当满足条件(r(i)≥r(2i)&&r()≥r(2i+1), i=1,2, ..). 时称之为大顶堆,此时,堆顶元素必为最大值。对于给定n个记录的例(()(2)...n)). 当且仅当满足条件(r(i)≤r(2i)&&r()≤r(2i+1),
i=1,2...n)时称之为小顶堆,此时,堆顶元素必为最小值。 

      堆排序的思想是对于给定的n个记录,初始时把这些记录看作-棵顺序存储的_ -叉树,然后将其调整为-一个大顶堆,再将堆的最后一个元素 与堆顶元素. (即二叉树的根结点)进行交换后,堆的最后- -个元素即为最大记录;接着将前(n-1) 个元素(即不包括最大记录)重新调整为一个大顶堆,再将堆顶元素与当前堆的最后-个元素进行交换后得到次大的记录,重复该过程直到调整的堆中只剩一个元素时为止,该远素即为最小记录,此时可得到一个有序序列。

二、堆排序过程:

1)将初始待排关键字序列(R1, R2...Rn) 构建成大顶堆,此堆为初始
的无区;
2)将堆顶元素R[1]与最后- -个元素R[n]交换,此时得到新的无序区
(R1, R2, ..Rn-1)和新的有序区(Rn), 且满足R[1, 2..n-1]sR[n];
3)由于交换后新的堆顶R[1]可能违反堆的性质,因此
需要对当前无序.
区(R1, R2,..-1)调整为新堆,然后再次将R[1]与无序区最后- 个元
素交换,得到新的无区(R1, R...n-2)和新的有序区(Rn-1, Rn)。
不断重复此过程直到有序区的元素个数为(n-1), 则整个排序过程完成。

三、堆排序算法代码:

function heapSort(arr)
{
    var heapSize = arr.length;
    var temp;
    // 建堆
    for(var i=Math.floor(heapSize/2)-1;i>=0;i--)
    {
        console.log("建堆");
        console.log("i:"+i);
        // for(let j=0;j<arr.length;j++)
        // {
        //     console.log("arr["+j+"] ="+arr[j]);
        // }
        heapify(arr,i,heapSize);
       
    }
    // 堆排序
    for(var j=heapSize-1;j>=1;j--)
    {
        console.log("堆排序");
        temp=arr[0];
        arr[0]= arr[j];
        arr[j] = temp;
        // for(let j=0;j<arr.length;j++)
        // {
        //     console.log("arr["+j+"] ="+arr[j]);
        // }
        heapify(arr,0,--heapSize);
    }
    return arr;
}
/** 
 * @param arr 数组
 * @param x 数组下标
 * @param len 堆大小
*/
function heapify(arr,x,len)
{
    var l = 2*x+1;
    var r = 2*x+2;
    var largset = x;
    var temp;
    if(l<len&&arr[l]>arr[largset])
    {
        largset =l;
    }
    if(r<len&&arr[r]>arr[largset])
    {
        largset=r;
    }
    console.log("L:"+l);
    console.log("R:"+r);
    console.log("x:",x);
    console.log("largset:"+largset);
    if(largset!=x)
    {
        temp = arr[x];
        arr[x] = arr[largset];
        arr[largset] = temp;
        // for(let j=0;j<arr.length;j++)
        // {
        //     console.log("arr["+j+"] ="+arr[j]);
        // }
        heapify(arr,largset,len);
    }
    
    
}

PS:其中注释部分,可以反注释来看其“大顶堆”的建立过程和堆的排序过程 。

四、测试代码:

var arr = [0,5,7,9,3,5,4];
var b = heapSort(arr);
console.log(b);

五、测试结果:

六、总结:

  对于堆建立的过程,其主要是,首先,要选出“大项堆”,然后然后其最大的数放在最后的位置,之后再重新建立一个新的“大项堆”,然后再和(len--)进行交换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flower in my heart

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值