算法导论之堆排序

本文详细介绍了一种高效的排序算法——堆排序。首先介绍了堆排序的基本原理,包括如何构建初始堆,并保持大顶堆性质。随后通过具体的Java代码示例,演示了如何实现堆排序算法,包括构建最大堆、调整堆结构等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆排序主要是先建堆,转化为最大堆,每次把最大的一个(即最大堆的根节点)和最后一个交换,这样每次都把当前最大的一个放到了最后。

堆排序算法中,最关键的就是构造初始堆。需要编写一个维护大顶堆性质的函数Max_Heapify。当输入一个数组L和一个下标i,然后调用Max_Heapify时,比较L[i]、L[left(i)]和L[right(i)]三者的大小;如果L[i]小于其孩子结点,就违背了大顶堆的性质,让L[i]和较大的孩子结点交换,实现在大顶堆中“降级”,从而使L[i]结点遵循大顶堆的性质。但交换后,以L[i]为根的子树又有可能违反最大堆的性质,因此对该子树递归的调用Max_Heapify函数。如调用Max_Heapify(L,2)后的递归过程。

 

维护堆的性质

//每次直接改变了数组elements
//堆就是用数组的形式存储的
//从零开始是左孩子是i* 2 + 1,右孩子是i* 2 + 2
//本方法是构建大顶堆(有小到大排序)
//构建后之后,每次再把最大的那个元素(也就是树的根节点)放到最后
//每次对去除最后已经ok的那个元素进行建堆
//大顶堆是表示把大的叶子节点调换到父节点上
public class HeapSort {
    public  static  void  heapSortfunction( int [] elements){
        for ( int  i = elements.length- 1 ; i >  0 ; i--){//每次是对element[0:i],这样是对去除最后已经ok的那个元素进行建堆
            buildHeap(elements,i); //建堆,建完之后是最大堆,也就是根节点是最大的
            swap(elements, 0 ,i); //交换根节点和最后一个节点,就是每次把当前最大的放在最后了
        }
    }

    private  static  void  buildHeap( int [] elements, int  lastIndex){//就是把elements【0:lastindex】变成最大堆
        int  lastParentIndex = (lastIndex- 1 )/ 2 ; //获得最后一个父节点,以便后面建堆
        // 下面的循环是到最后一个父节点,因为是父节点所以至少有一个左孩子
        for ( int  i = lastParentIndex; i >= 0 ; i--){
            int  parent = elements[i];
            int  leftChild = elements[i* 2 + 1 ]; //左节点肯定存在
            int  rightChild = leftChild;
            if (i* 2 + 2  <=lastIndex){//如果最后一个有右节点,就把对应的右节点赋给它
                //从零开始是左海子是i* 2 + 1,右孩子是i* 2 + 2
                rightChild = elements[i* 2 + 2 ]; //右节点不一定存在
            }
            int  maxIndex = leftChild<rightChild?i* 2 + 2 :i* 2 + 1 ;//把leftchild和rightchild中大的index给maxindex
            //从零开始是左孩子是i* 2 + 1,右孩子是i* 2 + 2
            if (parent < elements[maxIndex]){//如果parent小于左右孩子中的大的一个,就交换
                swap(elements,i,maxIndex);
            }
        }
    }

    private  static  void  swap( int [] elements, int  firstIndex, int  secondIndex){
        int  temp = elements[firstIndex];
        elements[firstIndex] = elements[secondIndex];
        elements[secondIndex] = temp;
    }

    public static void main(String[] args ){
        int a[]={2,3,1,5,8,9,3};
        heapSortfunction(a);
        for(int i=0;i<a.length;i++){
            System.out.print(a[i]+"  ");
        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值