声明:和小强一起学习数据结构java版本系列文章都是小强在学习程杰先生《大话数据结构》的过程中写的,因为程杰先生的《大话数据结构》是C语言版本的,小强只不过将C版本的程序在java版本中调通,然后把过程写下来。
堆排序
1. 概念
1) 堆
堆是完全二叉树。每一个节点的值都大于或者等于其左右孩子节点的值,称为大顶堆;每一个节点的值都小雨或等于其左右孩子节点的值称为小顶堆。
2) 堆排序(Heap Sort)
堆排序是对简单选择排序的一种改进,它可以做到在每次选择最小记录的同时,并根据比较结果对其他记录做出相应的调整,这样就比简单选择排序的效率高很多。
3) 堆排序思想
堆排序(Heap Sort)就是利用堆进行排序的算法,它将待排序的序列构造成一个大顶堆(其实就是从下往上,从右往左,将每个非叶子节点当做根节点,将其和其子树调整成大顶堆),此时,整个序列的最大值就是堆顶的根节点。将它移走(其实就是讲其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素的次小值,如此反复执行,就可以得到一个有序序列。
2. 验证代码
public class Java_Sort {
public static void main(String[] args) {
int[]values={0,50,10,90,30,70,40,80,60,20};
System.out.print("排序前数据为");
for(int i=0;i<values.length;i++){
System.out.print(" "+values[i]);
}
HeapSort.HeapSort1(values);
System.out.print("\n");
System.out.print("排序后数据为:");
for(int i=0;i<values.length;i++){
System.out.print(" "+values[i]);
}
}
}
3. 程序示例与讲解
public class HeapSort {
public static void Heap_build(int[] args ,int s,int m){
//临时变量,用于存储每次进行比较的父节点的值
int temp=0;
//临时变量,用于存储每次进行比较的子节点位置
int j=0;
//temp存储每次比较父节点的值
temp=args[s];
for(j=2*s;j<=m;j*=2){
//找出左右孩子节点中最大的
if(j<m&&args[j]<args[j+1]){//判断做孩子节点是否小于有孩子节点
++j; //如果左孩子节点小于右孩子节点,则j指向右孩子节点
}
//拿父节点跟左右孩子节点相比较,如果父节点大于左右孩子节点,则退出此次比较
if(temp>args[j])break;
//如果父节点小于左右孩子节点,则把左右孩子节点中大的赋值给父节点
args[s]=args[j];
s=j;
}
//本次比较完成之后,把原来保存起来的父节点的值,赋值给左孩子节点中大的那个
args[s]=temp;
}
public static void HeapSort1(int[] args){
int temp=0;
//将待排序序列构建成堆
for(int i=args.length/2;i>0;i--){
Heap_build(args,i,args.length-1);
}
//将构建好的堆进行排序
for(int i=args.length-1;i>0;i--){
//将堆顶记录和当前未经排序的子序列最后一个记录交换
if(args[1]>args[i]){
temp = args[1];
args[1]=args[i];
args[i]=temp;
}
//重新将剩余的数据构建堆
Heap_build(args,1,i-1);
}
}
}
验证结果:
排序前数据为: 0 50 10 90 30 70 40 80 60 20
排序后数据为: 0 10 20 30 40 50 60 70 80 90
4) 图示说明
Ø 建堆阶段图示说明
Ø 排序阶段