java实现-数据结构之二叉树(四):堆排序

数据结构之二叉树(四):堆排序

基本介绍

堆排序是一种选择排序,它的最坏,最好,平均实践复杂度均为O(nlogn),它也是不稳定排序

堆介绍:
堆是一种有特殊性质的完全二叉树
大顶堆
每个节点的值都大于或者等于其左右子节点的值。
小顶堆
每个节点的值都小于或者等于其左右子节点的值。

大顶堆示意图
在这里插入图片描述
我们按堆中的节点按层进行编号,映射到数组中就是 arr[50,45,40,20,25,35,30,10,15];
即arr[i]>=arr[2i+1]&&arr[i]>=arr[2i+2];(i是对应的节点编号)
(注意:大小顶堆都没有要求左右子节点之间的大小关系)。

小顶堆示意图
在这里插入图片描述
即arr[i]<=arr[2i+1]&&arr[i]<=arr[2i+2].

堆排序:
一般升序采用大顶堆,降序采用小顶堆。

堆排序基本思想:
1.先将待排序序列构造成一个大顶堆。
2.这时整个序列的最大值便是该大顶堆的根节点。
3.把这个根节点的值与待排序序列的末尾值进行交换,这个时候末尾就是最大值。
4.然后将剩下的n-1个树重新构造成一个堆,这样会得到一个n-1个元素中的最大值,再此与着n-1个元素的末尾元素进行交换。
5.如此反复执行,就能得到一个升序的有序序列。

图解实例:
首先我们先定义一个数组:
arr[4,5,8,5,9]
把它构造成一颗树如图:
在这里插入图片描述
按照思路,接下来要做的便是将其构造成一棵大顶堆。
将其构造成一棵大顶堆的思路如下:
1.首先我们先找到该树的最后一个非叶子节点(arr.length/2-1可得)(也就是节点6),让6节点与其左右子节点比较,取三者中的最大值与节点6进行交换。
交换结果如下:
在这里插入图片描述
于是树相对应的数组便变成了
arr[4,9,8,5,6]

2.接着从左至右,从下至上进行调整
再找到第二个非叶子节点(也就是4节点)同样进行比较交换,得到如下:
在这里插入图片描述
3.此时发现替换后的节点4仍比它的左右子节点小,再次交换,最后得到如下:
在这里插入图片描述
此时得到数组
arr[9,6,8,5,4]
接着将root节点(9节点)与末尾进行交换,得到如下:
在这里插入图片描述
最后以此类推,不断进行比较交换置后,最后便得到了一个升序数组。

java参考代码如下:

import java.util.Arrays;

public class HeapSort {
    
    
	public static void main(String[] args) {
    
    
		//升序排列
		int arr[]= {
    
    4,6,8,5,9};
		heapSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	//堆排序方法
	public static void heapSort(int[] arr) {
    
    
		int temp=0;
		for(int i=arr.length/2-1;i>=0;i--) {
    
    
			makeBigHeap(arr,i,arr.length);
		}
		for(int j=arr.length-1;j>0;j--) {
    
    
			temp=arr[j];
			arr[j]=arr[0];
			arr[0]=temp;
			makeBigHeap(arr,0,j);
		}
		
	}
	
	/*
	 * 将数组调整成大顶堆的方法:将以i对应的非叶子节点树调整成大顶堆
	 * arr:待调整数组
	 * i:非叶子节点在数组中索引
	 * length:调整数组的长度
	 */
	public static void makeBigHeap(int arr[],int i,int length) {
    
    
		int temp=arr[i];//取出当前元素,保存在临时变量
		//k=i*2+1,k是i节点的左子节点
		for(int k=i*2+1;k<length;k=k*2+1) {
    
    
			if(k+1<length&&arr[k]<arr[k+1]) {
    
    
				k++;//k指向右子节点
			}
			if(arr[k]>temp) {
    
    //如果子节点大于父节点
				arr[i]=arr[k];//把较大的值赋值给当前节点
				i=k;//继续循环比较
			}else {
    
    
				break;
			}
		}
		arr[i]=temp;//将temp赋值放到调整后的位置

	}
}

猜你喜欢

转载自blog.csdn.net/qq_45273552/article/details/109101049