一步一步解析java排序算法---堆排序(最大堆)

与最小堆(递减)类似:
最大堆(递增)的调整操作:

        //从i节点开始调整, i节点的子节点为 2*i+1, 2*i+2  
        public static void MaxHeapFixdown(int a[], int i, int n)  
        {  
            int j, temp;  

            temp = a[i]; //取出节点值,比较,替换 
            j = 2 * i + 1;  //左子节点
            while (j < n)  
            {  
                if (j + 1 < n && a[j + 1] > a[j]) //在左右子节点中找最大的  
                    j++;  

                if (a[j] <= temp)  //说明已经排好序
                    break;  

                a[i] = a[j];     //把较大的子结点往上移动,替换它的父结点  
                i = j;  
                j = 2 * i + 1;  //继续往下遍历比较
            }  
            a[i] = temp; //调整结束 
        }    

建立最大堆:

        /**
         * 建立最大堆  
         * 对数组中的每个元素进行子节点调整,最大的向上移动
         * @param a 数组
         * @param n 数组长度
         */
        static void MakeMaxHeap(int a[], int n)  
        {  
            //n/2-1可以定位到最后一个数组元素了,子节点分别为n-2,n-1
            for (int i = n / 2 - 1; i >= 0; i--)  
                MaxHeapFixdown(a, i, n);  
        }  

堆排序:

        public static void MaxheapsortTodescendarray(int a[], int n)  
        {  
            for (int i = n ; i >= 1; i--)  
            {  
                MakeMaxHeap(a,i);//从根节点调整定位最小值,调整过后a[0]最大
                swap(a,i-1,0);//交换值,此时a[0]最大,进行下沉;下次遍历进行调整不会调整a[i-1]
            }  
        }  
        public static void swap(int a[],int i,int j){
            int temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }

此时的数组是递增数组;

    public static void main(String[] args) {
        int[] unsort={2,24,8,40,80,100,1,563,55};
        MaxheapsortTodescendarray(unsort, unsort.length);
        for (int i = 0; i < unsort.length; i++) {
            System.out.print("  "+unsort[i]);
        }

    }

运行结果:

1 2 8 24 40 55 80 100 563

完整代码贴出:

        //从i节点开始调整, i节点的子节点为 2*i+1, 2*i+2
        public static void MinHeapFixdown(int a[], int i, int n)  
        {  
            int j, temp;  

            temp = a[i]; //取出节点值,比较,替换 
            j = 2 * i + 1;  //左子节点
            while (j < n)  
            {  
                if (j + 1 < n && a[j + 1] < a[j]) //在左右子节点中找最小的  
                    j++;  

                if (a[j] >= temp)  //说明已经排好序
                    break;  

                a[i] = a[j];     //把较小的子结点往上移动,替换它的父结点  
                i = j;  
                j = 2 * i + 1;  //继续往下遍历比较
            }  
            a[i] = temp; //调整结束 
        }    
        //从i节点开始调整, i节点的子节点为 2*i+1, 2*i+2  
        public static void MaxHeapFixdown(int a[], int i, int n)  
        {  
            int j, temp;  

            temp = a[i]; //取出节点值,比较,替换 
            j = 2 * i + 1;  //左子节点
            while (j < n)  
            {  
                if (j + 1 < n && a[j + 1] > a[j]) //在左右子节点中找最大的  
                    j++;  

                if (a[j] <= temp)  //说明已经排好序
                    break;  

                a[i] = a[j];     //把较大的子结点往上移动,替换它的父结点  
                i = j;  
                j = 2 * i + 1;  //继续往下遍历比较
            }  
            a[i] = temp; //调整结束 
        }    
        /**
         * 建立最小堆  
         * 对数组中的每个元素进行子节点调整,最小的向上移动
         * @param a 数组
         * @param n 数组长度
         */
        static void MakeMinHeap(int a[], int n)  
        {  
            //n/2-1可以定位到最后一个数组元素了,子节点分别为n-2,n-1
            for (int i = n / 2 - 1; i >= 0; i--)  
                MinHeapFixdown(a, i, n);  
        }  
        /**
         * 建立最大堆  
         * 对数组中的每个元素进行子节点调整,最大的向上移动
         * @param a 数组
         * @param n 数组长度
         */
        static void MakeMaxHeap(int a[], int n)  
        {  
            //n/2-1可以定位到最后一个数组元素了,子节点分别为n-2,n-1
            for (int i = n / 2 - 1; i >= 0; i--)  
                MaxHeapFixdown(a, i, n);  
        }  
        public static void MinheapsortTodescendarray(int a[], int n)  
        {  
            for (int i = n ; i >= 1; i--)  
            {  
                MakeMinHeap(a,i);//从根节点调整定位最小值,调整过后a[0]最小 
                swap(a,i-1,0);//交换值,此时a[0]最小,进行下沉;下次遍历进行调整不会调整a[i-1]
            }  
        }  
        public static void MaxheapsortTodescendarray(int a[], int n)  
        {  
            for (int i = n ; i >= 1; i--)  
            {  
                MakeMaxHeap(a,i);//从根节点调整定位最小值,调整过后a[0]最大
                swap(a,i-1,0);//交换值,此时a[0]最大,进行下沉;下次遍历进行调整不会调整a[i-1]
            }  
        }  
        public static void swap(int a[],int i,int j){
            int temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值