堆排序(java)
堆排序就是一颗树🌲,每一次的遍历都会把整颗树中值最大的节点送往根节点,然后摘掉这个根节点放入结果数组,再继续,直到树被掏空。
先拆分成一个小问题来看,这颗mini树内部进行对比交换,最后最大的值应该是root节点
然后放眼来看整颗树🌲,一轮对比下来,最大的应该在树顶
每轮结束后,将树顶的节点投入到结果数组中
经过N(N为原数组长度)轮后,树就已经被完全掏空了,结果数组也已经填满了
java实现
import java.util.ArrayList;
public class Sort{
public static ArrayList<Integer> heapsort(ArrayList<Integer> origin){
ArrayList<Integer> res=new ArrayList<>();
while(!origin.isEmpty()){//直到树被完全掏空
if(origin.size()>1){
origin=nodeswap(origin, 0);
}
res.add(origin.get(0));//将树顶投入到结果数组当中
origin.remove(0);
}
return res;
}
public static ArrayList<Integer> nodeswap(ArrayList<Integer> origin,int pos){
int leftpos=pos*2+1;int rightpos=pos*2+2;//左右节点位置坐标
int maxpos;int mid;
if(leftpos>=origin.size()){//没有左右节点,不对树做处理
return origin;
}else{
origin=nodeswap(origin, leftpos);
maxpos=leftpos;//最大值默认左边节点,如果右边大于左边,则为右边
if(rightpos<origin.size()){
origin=nodeswap(origin, rightpos);
if(origin.get(rightpos)>origin.get(leftpos)){
maxpos=rightpos;
}
}
if (origin.get(maxpos)<origin.get(pos)) {
maxpos=pos;//如果左右最大的节点都小于根节点,则数组保持不变
}else{
//否则需要换位
mid=origin.get(pos);
origin.set(pos, origin.get(maxpos));
origin.set(maxpos, mid);
}
}
return origin;
}
}