菜单

堆排序 JAVA实现

duckflew
发布于 2020-12-28 / 242 阅读
0
0

堆排序 JAVA实现

堆排序的思想是 先把需要排序的数组构造成一个大根堆或者小根堆 然后用选择排序的思想 每一次都从堆里面选取最小的元素放到已经有序的序列中去 交换完成后对 被取走根的堆重建 其中在建立堆和调整堆的时候都需要用到一个方法来调整 这里我命名为一个adjustHeal(arr ,index,endIndex)
其中index代表的是需要调整的节点的位置 endindex是指本次需要调整的结束的位置(结束位置有效)代码如下

 public static void adjustHeal(int[] arr,int index,int endIndex)
    {
        int adjustIndex=index;
        int max=adjustIndex*2+1;
        int temp;
        while (max<=endIndex)
        {
            if (max+1<=endIndex&&arr[max]<arr[max+1])//左孩子小于右孩子
                max++;
            if (arr[adjustIndex]>arr[max])break;
            else
            {
                temp=arr[adjustIndex];
                arr[adjustIndex]=arr[max];
                arr[max]=temp;
            }
            /**
             * 更新 需要调整的节点的位置  以及孩子的位置  准备进入下一轮调整
             */
            adjustIndex=max;
            max=adjustIndex*2+1;
        }
    }

首先是定义一个adjustIndex 表示当前已经进行到的 需要调整的节点位置
max 就是左孩子或者是右孩子 具体是那个 通过下面的判断来确定 如果是大根堆 那就取最大 反之取小的那个
此时如果当前的需要调整的节点已经满足最大堆的特点也就是
if (arr[adjustIndex]>arr[max])break;
了 那就停止
否则的话交换 需要调整的节点和较大孩子节点的值 构造大根堆
然后给adjustIndex和max重新赋值 从而进入下一轮的调整
这个调整会一直到当前已经满足大根堆的特点或者 到了叶子节点才结束

堆的调整方法写完了 就可以开始写排序函数了 ,排序函数其实没有什么

  • 先建堆 这里建立堆的时候要注意一个问题就是 要从最后一个非叶子节点开始建 从下往上 因为写的adjustHeal方法是 对于一个节点一直往下调整 知道遇到它的孩子节点满足了堆的性质就结束了 然而并不会检查 孩子的孩子是否满足性质 所以我们要从底部开始建立堆 这样就可以保证在调整堆 那个while循环终止的时候 儿子节点们都是满足堆的性质的 (最后一个非叶子节点 通过arr.length/2-1得出
  • 然后就是一共要循环 arr.length-1次 选择这么多次最小或者最大的 从而就达到了排序的效果了 跟普通的选择排序一样 每次把堆顶部的元素跟尾部的第一个未排序的元素交换 这里的排序有序区是放在后面的 例如i=1的时候 整个数组是个大根堆 那排序区目前还没有元素 由于我们是要从小到大排序 所以应该把最大的元素依次放在最后面 较后面 次后面 如此下去 所以用temp=arr[arr.length-i];和下面的两句来交换
  • 下面是一个数组样例的排序过程
原数组:  [7, 2, 35, 0, 10, 14, 47]
建堆完成后的数组: [47, 10, 35, 0, 2, 14, 7]
下面是整个过程:
[47, 10, 35, 0, 2, 14, 7]
[35, 10, 14, 0, 2, 7, 47]
[14, 10, 7, 0, 2, 35, 47]
[10, 2, 7, 0, 14, 35, 47]
[7, 2, 0, 10, 14, 35, 47]
[2, 0, 7, 10, 14, 35, 47]
排序后的数组: [0, 2, 7, 10, 14, 35, 47]

代码如下

 public static void healSort(int [] arr)
    {
        for (int i = arr.length/2-1; i >=0 ; i--)
            adjustHeal(arr,i,arr.length-1);

        int temp;
        for (int i = 1; i < arr.length; i++)
        {
            temp=arr[arr.length-i];
            arr[arr.length-i]=arr[0];
            arr[0]=temp;
            adjustHeal(arr,0,arr.length-i-1);
        }
    }

评论