堆排序算法

package sort;

/**
 * HeapSort 
 * 堆排序算法:
 * 基本思想:利用堆积树(堆)这种资料结构所设计的一种排序算法, 可以利用数组的特点快速定位指定索引的元素。
 * 堆排序是不稳定的排序方法,辅助空间为O(1), 最坏时间复杂度为O(nlog2n) , 堆排序的堆序的平均性能较接近于最坏性能。
 * 
 * 大根堆排序算法的基本操作: 
 * ① 初始化操作:将R[1..n]构造为初始堆; 
 * ②每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。
 * ①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。
 * ②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反
 * :在任何时刻堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。
 * 
 */

public class HeapSort
{
    private int countStep = 0;

    public void sort(int[] initData)
    {
        int len = initData.length;
        
        heap_sort(initData, len-1);
    }

    public void heap_sort(int[] arrays, int end)
    {
        if (end > 0)
        {
            init_sort(arrays, end);// 初始化堆,找出最大的放在堆顶,即放在0的位置
            arrays[0] = arrays[end] + arrays[0];
            arrays[end] = arrays[0] - arrays[end];
            arrays[0] = arrays[0] - arrays[end];
            heap_sort(arrays, end - 1);
        }
    }

    public void init_sort(int[] arrays, int end)
    {
        int m = (end + 1) / 2;
        for (int i = 0; i < m; i++)
        {
            boolean flag = build_heap(arrays, end, i);
            //如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
            if(flag)
            {
                i=-1;
            }
        }
    }

    public boolean build_heap(int arrays[], int end, int i)
    {
        int l_child = 2 * i + 1;// 左孩子
        int r_child = 2 * i + 2;// 右孩子
        
        countStep ++;
        
        if (r_child > end)
        { // 判断是否有右孩子,没有的话直接比较,小于交换
            if (arrays[i] < arrays[l_child])
            {
                arrays[i] = arrays[i] + arrays[l_child];
                arrays[l_child] = arrays[i] - arrays[l_child];
                arrays[i] = arrays[i] - arrays[l_child];
                return true;
            }
            else
            {
                return false;
            }
        }
        // 在根与两个孩子之间找出最大的那个值进行交换
        if (arrays[i] < arrays[l_child])
        {
            if (arrays[l_child] > arrays[r_child])
            {
                // 交换根与左孩子的值
                arrays[i] = arrays[i] + arrays[l_child];
                arrays[l_child] = arrays[i] - arrays[l_child];
                arrays[i] = arrays[i] - arrays[l_child];
                return true;
            }
            else
            {
                // 交换根与右孩子的值
                arrays[i] = arrays[i] + arrays[r_child];
                arrays[r_child] = arrays[i] - arrays[r_child];
                arrays[i] = arrays[i] - arrays[r_child];
                return true;
            }
        }
        else if (arrays[i] < arrays[r_child])
        {
            // 交换根与右孩子的值
            arrays[i] = arrays[i] + arrays[r_child];
            arrays[r_child] = arrays[i] - arrays[r_child];
            arrays[i] = arrays[i] - arrays[r_child];
            return true;
        }
        return false;

    }

    public int showStep()
    {
        return countStep;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值