从零单刷数据结构(Java描述)(二十六)——排序之堆排序

堆排序(Heap Sort)是利用堆(本文使用大顶堆)进行排序的方法。它的基本思想是, 将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值) ,然后将剩余的 n-1 个序列重新构造成一个堆,这样就得到 n 个元素中的次小值。如此反复执行, 便能得到一个有序序列了。堆排序是一种不稳定的排序算法,复杂度O(nlogn)。

堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

大顶堆、小顶堆:
在这里插入图片描述

import java.util.Arrays;
//测试类
public class HeapSort {

	public static void main(String[] args) {
		int[]arr=new int[] {9,6,8,7,0,1,10,4,2};
		heapSort(arr);
		//输出:[0, 1, 2, 4, 6, 7, 8, 9, 10]
		System.out.println(Arrays.toString(arr));
	}

	//堆排序
	public static void heapSort(int[]arr) {
		//开始位置是最后一个非叶子结点,即最后一个结点的父节点
		int start=(arr.length-1)/2;
		//调整为大顶堆
		for (int i = start; i >=0; i--) {
			maxHeap(arr,arr.length,i);
		}
		//先把数组中的第0个和堆中的最后一个数交换位置,再把前面的处理为大顶堆
		for (int i = arr.length-1; i >0; i--) {
			int temp=arr[0];
			arr[0]=arr[i];
			arr[i]=temp;
			maxHeap(arr, i, 0);
		}
	}
	
	//构建大顶堆
	public static void maxHeap(int[] arr, int size, int index) {
		// TODO Auto-generated method stub
		//左子结点
		int leftNode=2*index+1;
		//右子结点
		int rightNode=2*index+2;
		int max=index;
		//和两个子结点分别对比,找出最大的结点
		if(leftNode<size && arr[leftNode]>arr[max])
			max=leftNode;
		if(rightNode<size && arr[rightNode]>arr[max])
			max=rightNode;
		//交换位置
		if(max!=index) {
			int tmp=arr[index];
			arr[index]=arr[max];
			arr[max]=tmp;
			//交换位置以后,可能会破坏之前排好序的堆,所以,之前排好的堆需要重新调整
			maxHeap(arr, size, max);
	}
		}

}

猜你喜欢

转载自blog.csdn.net/waS_TransvolnoS/article/details/92072945
今日推荐