排序:堆排序

堆排序是顺序存储的完全二叉树,保证父节点不小于(大于)子节点
先排成完全二叉树,然后从最后一个非叶子几点开始构建堆
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);
}


posted on   zawjdbb  阅读(147)  评论(0编辑  收藏  举报

编辑推荐:
· ASP.NET Core - 日志记录系统(二)
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
阅读排行:
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(一):从.NET IoT入
· .NET 开发的分流抢票软件,不做广告、不收集隐私
· ASP.NET Core - 日志记录系统(二)
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· 实现windows下简单的自动化窗口管理

导航

< 2025年1月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8

统计

点击右上角即可分享
微信分享提示