堆排序:堆分为最大堆和最小堆。
最大堆:它的值大于它所有的子孙代表的值。
最小堆:它的值小于它所有的子孙代表的值。
插入:将新添加的值,添加到堆的最后位置,然后重新构建堆。
删除:将根节点的值移除,将最后的节点值填补根节点值,然后重新构建堆。
节点i 父节点(i-1)/2 子节点 (left)2*i+1 (right) 2*i+2
堆排序属于非稳定性排序。
以下是代码部分:
package com.scy.arithmetic;
import java.util.Arrays;
/**
* @author suda
*堆排序思想:讲给的数组变化成最大堆或者最小堆,然后进行删除操作进行排序。
*插入操作思想:在最后的子节点出添加一个新的节点放入插入的值,然后进行最大堆或最小堆操作
*删除思想:将根节点数去除,然后用最后一个的节点数放在根节点,然后进行最大堆或最小堆操作
*/
public class StackSort {
public static void main(String[] args) {
//生成一个随机的20位数组
int[] a=new int[20];
for (int i = 0; i <20; i++) {
a[i]=(int)(Math.random()*(100-1+1)+1);
}
//打印生成的数组
System.out.println(Arrays.toString(a));
/*//构建最大堆
new StackSort().maxStack(a, a.length-1);
System.out.println(Arrays.toString(a));
//构建最小堆
new StackSort().minStack(a, a.length-1);
System.out.println(Arrays.toString(a));
//进行堆排序,结果由大到小排列
new StackSort().stackSort(a);
System.out.println(Arrays.toString(a));*/
//进行插入操作,构建最大堆
new StackSort().maxStack(a, a.length-1);
new StackSort().insetStack(a, 80);
}
//插入新数据,a为最大堆.思想:将新值放到最后的位置
public void insetStack(int[] a,int b){
int[] c=new int[a.length+1];
for (int i = 0; i < a.length; i++) {
c[i]=a[i];
}
c[a.length]=b;
maxStack(c, c.length-1);
System.out.println(Arrays.toString(c));
}
//堆排序,又称删除操作,传入的是最大堆或者最小堆
public void stackSort(int[] a){
for (int i = a.length-1; i >0; i--) {
//因为要求从大到小排列,则需要建立最小堆
minStack(a, i);
int temp=a[0];
a[0]=a[i];
a[i]=temp;
}
}
//构建最小堆,思想:所有的节点均小于它的子孙节点。
public void minStack(int[] a,int len){
for (int i = len; i>(len-1)/2; i--) {
for (int j = i; j>0; j=(j-1)/2) {
for (int j2 =(j-1)/2; j2>=0; j2=(j2-1)/2) {
//如果辈分最小的代表数组大于它的祖宗辈所表示的值,则进行值的交换
if(a[j]<a[j2]){
int temp=a[j];
a[j]=a[j2];
a[j2]=temp;
}
if(j2==0){
break;
}
}
}
}
}
//构建最大堆,思想:所有的节点均大于它的子孙节点。
public void maxStack(int[] a,int len){
//只需要将最后一代进行分组,然后分别跟它对应的祖辈进行比较排序
for (int i = len; i>(len-1)/2; i--) {
//借用选择排序的思想,用最后一个跟它上边的依次比较,让最后一个是最小值。最后一个在移位到上一个的位置继续比较。
for (int j = i; j>0; j=((j-1)/2)) {
//祖孙数组中的祖宗辈,及爸爸,爷爷,老爷爷。。。知道老祖宗
for (int j2 = ((j-1)/2); j2>=0; j2=((j2-1)/2)) {
//如果最小的比它的祖宗大,则进行辈分交换
if(a[j]>a[j2]){
int temp=a[j];
a[j]=a[j2];
a[j2]=temp;
}
//如果已经跟祖宗比较完了,则本轮比较
if(j2==0){
break;
}
}
}
}
}
}