排序算法--选择排序--堆排序

https://blog.csdn.net/u010452388/article/details/81283998 

基本思想:

1.首先将待排序的数组构造成一个大根堆,此时,整个数组的最大值就是堆结构的顶端

2.将顶端的数与末尾的数交换,此时,末尾的数为最大值,剩余待排序数组个数为n-1

3.将剩余的n-1个数再构造成大根堆,再将顶端数与n-1位置的数交换,如此反复执行,便能得到有序数组


import org.junit.Test;

import java.util.Random;

/**
 * Author:zxh
 * MIS: 
 * Date: 2019/2/21 19:53
 * Email: 
 * Desc: 大顶堆 并不仅仅要求0位置的值最大,而且要求每个父节点都大于左孩子,右孩子
 */
public class SortHeap {

    private final static int arrLength = 10;

    @Test
    public void test() {
        //int[] a = {6, 0, 8, 19, 20, 31, 59, 71, 79, 95,};

        /*初始化数组*/
        int[] a = new int[arrLength];
        Random random = new Random();
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(100);
        }
        System.out.print("原始数组:");
        print(a);

        /*构建大顶堆*/
        generateMaxTopHeap(a);
        System.out.print("初始化构建大顶堆完毕后:");
        print(a);

        /*堆顶与最后一位元素交换*/
        swap(a, a.length - 1, 0);

        /*重新构建大顶堆**/
        rebulidMaxTopHeap(a);

        print(a);
    }

    private void rebulidMaxTopHeap(int[] a) {
        int parentIndex;
        //父、左、右中的最大的index
        int maxIndex;
        //最后一个节点
        int lastIndex = a.length - 2;
        while (lastIndex >= 1) {
            parentIndex = 0;
            int leftIndex = 2 * parentIndex + 1;
            int rightIndex = 2 * parentIndex + 2;
            while (leftIndex <= lastIndex) {
                /*rightIndex > lastIndex时,右孩子已经是排好序的,不能重新把它卷进来,只需比较左孩子和父节点*/
                if (a[leftIndex] > a[rightIndex] || rightIndex > lastIndex) {
                    maxIndex = leftIndex;
                } else {
                    maxIndex = rightIndex;
                }
                if (a[parentIndex] > a[maxIndex]) {
                    break;
                }

                swap(a, maxIndex, parentIndex);

                parentIndex = maxIndex;
                leftIndex = 2 * parentIndex + 1;
                rightIndex = 2 * parentIndex + 2;
            }

            swap(a, 0, lastIndex);

            lastIndex--;

            System.out.print("中间选择排序过程:");
            print(a);
        }
    }

    private void generateMaxTopHeap(int[] a) {
        int childIndex;
        int parentIndex;
        for (int index = 1; index < a.length; index++) {
            //父节点 parent = (child-1)/2
            childIndex = index;
            parentIndex = (childIndex - 1) / 2;

            while (childIndex > 0) {
                if (a[childIndex] > a[parentIndex]) {
                    swap(a, parentIndex, childIndex);
                }
                childIndex = parentIndex;
                parentIndex = (parentIndex - 1) / 2;
            }
        }
    }

    private void swap(int[] a, int aIndex, int bIndex) {
        int temp = a[bIndex];
        a[bIndex] = a[aIndex];
        a[aIndex] = temp;
    }

    public void print(int[] array) {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + ",");
        }
        System.out.println();
    }


    public static void main(String[] args) {
        System.out.println((0 - 1) / 2);// 输出0  ********
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值