堆排序是顺序存储的完全二叉树,保证父节点不小于(大于)子节点
先排成完全二叉树,然后从最后一个非叶子几点开始构建堆
java实现:
import java.util.*;
import java.util.regex.Pattern;
public class Heap_Sort {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String s = in.nextLine().replace(" ", ""); //只针对0到9,范围以外需要修改输入判断
int len = s.length();
for(int i = 0; i < len; i++){ //去除无用空格,只针对0到9,范围以外需要修改输入判断
list.add(Integer.parseInt(String.valueOf(s.charAt(i))));
}
int[] sorted = new int[len];
for(int i = 0; i < len; i++){
h_sort(list);
sorted[i] = list.get(0);
list.set(0, list.get(len-i-1));
list.remove(len-i-1);
}
System.out.println(Arrays.toString(sorted));
}
}
//按大小交换父子节点,返回交换的地方,方便继续深入探测修改
private static String exchange(List<Integer> list, int key){
int len = list.size();
int left = key*2+1;
if(key*2+2 < len){
int right = key*2+2;
if(list.get(key) < list.get(left) || list.get(key) < list.get(right)){ //判断子节点是否有大于父节点的,即是否需要交换
if(list.get(left) > list.get(right)){ //判断从哪个子节点交换,和最大的交换
int temp = list.get(key);
list.set(key, list.get(left));
list.set(left, temp);
return "left";
}else{
int temp = list.get(key);
list.set(key, list.get(right));
list.set(right, temp);
return "right";
}
}else{
return "no change";
}
}else if(list.get(key) < list.get(left)){ //只有左子节点时
int temp = list.get(key);
list.set(key, list.get(left));
list.set(left, temp);
return "left";
}else{
return "no change";
}
}
//把传入的ArrayList变为大顶堆
private static void h_sort(List list){
int len = list.size();
for(int i = len/2-1; i >= 0; i--){ //length/2-1为最后一个拥有有子节点的节点位置
int key = i;
while(key*2+1 < len) {
String flag = exchange(list, key);
if(flag.equals("left")) { //和左子交换,定位到左子看是否破坏了左子树的堆排序
key = key*2+1;
}else if(flag.equals("right")){ //和右子交换,定位到左子看是否破坏了左子树的堆排序
key = key*2+2;
}else if(flag.equals("no change")){ //没发生交换,即子树也不会被破坏,无需继续深入
break;
}
}
}
}
}
js实现:
function exchange(arr,n){
var temp = arr[n-1];
if((arr[n-1]>arr[2*n-1]) || (arr[n-1]>arr[2*n])){
if(arr[2*n] != undefined) {
if (arr[2 * n - 1] <= arr[2 * n]) {
arr[n - 1] = arr[2 * n - 1];
arr[2 * n - 1] = temp;
return 0;
}
else {
arr[n - 1] = arr[2 * n];
arr[2 * n] = temp;
return 1;
}
}
else{
arr[n-1] = arr[2*n-1];
arr[2*n-1] = temp;
return 0;
}
}
}
function heap_sort(array){
var arr = array.concat();
var lenAll = arr.length;
var len = parseInt(lenAll/2);
for(var i = len; i > 0; i--){
var key = i;
var flag;
while(key < lenAll){
flag = exchange(arr,key);
if(flag == 0) {
key = 2 * key;
}
else{
key = 2 * key + 1;
}
}
}
return arr;
}
function heap_print(array){
var result = [];
var arr = array.concat();
var len = array.length;
for(var i = 0; i < len; i++){
arr = heap_sort(arr);
var temp = arr.concat();
var first = arr.shift();
var last = arr.pop();
arr.unshift(last);
arr.push(first);
result.push(arr.pop());
}
alert(result);
}