堆排序Heapsort的Java和C代码
Heapsort排序思路
将整个数组看作一个二叉树heap, 下标0为堆顶层, 下标1, 2为次顶层, 然后每层就是"3,4,5,6", "7, 8, 9, 10, 11, 12, 13, 14", ..., 对于其中的每一个非叶子节点, 其子节点的下标为 2 * pos + 1 和 2 * pos + 2
循环进行以下工作:
- 标记当前堆的右边界
- 将堆初始化为大顶堆
- 将堆顶置换到右边界, 同时将右边界左移一位(即将堆缩小一格)
将堆初始化为大顶堆的处理
- 从最后一个非叶子节点开始, 其下标为 length / 2 - 1, length为当前的堆大小, 往前挨个处理
- 检查节点值, 对节点与其子节点的值大小i进行比较, 如果子节点值比当前节点大, 将最大值的那个子节点换上来
- 如果发生了交换, 那么要对发生交换的这个子节点位置也进行检查, 如果还有交换, 则继续往下查, 直到达到叶子节点
public class DemoHeapSort {
// 待排序的数组
private int[] ints;
// 当前堆的右边界(下标)
private int limit;
public DemoHeapSort(int ... ints) {
this.ints = ints;
this.limit = ints.length - 1;
}
public void sortAll() {
while (limit > 0) {
resort();
swap(0, limit);
limit--;
}
}
public void resort() {
// 起点pos为当前堆length / 2 - 1
for (int i = (limit + 1) / 2 - 1; i >= 0; i--) {
int pos = i;
while (true) {
pos = check(pos);
if (pos == 0) {
break;
}
}
}
}
/**
* 检查pos位置, 自上而下判断是否都满足大顶堆的要求
* 其左右子节点的下标为 2*pos+1 和 2*pos+2
*
* @param pos 当前要检查的下标
* @return 如果无调整, 则返回0, 如果有调整, 则返回被调整的子节点下标
*/
private int check(int pos) {
int posLeft = 2 * pos + 1;
int posRight = 2 * pos + 2;
if (posLeft > limit) { // 没有子节点
return 0;
}
if (posRight > limit) { // 仅有左节点
if (ints[pos] < ints[posLeft]) {
swap(pos, posLeft);
return posLeft;
} else {
return 0;
}
}
// 左右节点都有
if (ints[posLeft] > ints[posRight]) {
if (ints[pos] < ints[posLeft]) {
swap(pos, posLeft);
return posLeft;
} else {
return 0;
}
} else {
if (ints[pos] < ints[posRight]) {
swap(pos, posRight);
return posRight;
} else {
return 0;
}
}
}
public void print() {
for (int a : ints) {
System.out.printf("%3d", a);
}
System.out.print("\n");
}
private void swap(int a, int b) {
int tmp = ints[a];
ints[a] = ints[b];
ints[b] = tmp;
}
public static void main(String[] args) {
DemoHeapSort hs = new DemoHeapSort(10, 97, 9, 1,63, 64, 8, 17, 33, 7, 21, 0, 7, 75, 13, 18, 2, 99, 87);
hs.sortAll();
hs.print();
}
}
C代码, 在原数组上排序
void heap_sort(int *nums, int size) {
for (int i = 0; i < size; i++) {
int num = *(nums + i);
printf("%d ", num);
}
printf("\n");
for (int i = 0; i < size; i++) {
int length = size - i;
for (int pos = length / 2 - 1; pos >= 0; pos-- ) {
int p = pos;
do {
p = check(nums + i, length - 1, p);
} while (p != 0);
}
for (int j = 0; j < size; j++) {
int num = *(nums + j);
printf("%d ", num);
}
printf(" %d\n", i);
}
}
int check(int *nums, int limit, int pos) {
int ls = pos * 2 + 1;
int rs = pos * 2 + 2;
if (ls > limit) {
return 0;
}
int p = *(nums + pos);
if (rs > limit) {
int l = *(nums + ls);
if (l > p) {
swap(nums + ls, nums + pos);
return ls;
} else {
return 0;
}
} else {
int l = *(nums + ls);
int r = *(nums + rs);
if (l > r) {
if (l > p) {
swap(nums + ls, nums + pos);
return ls;
} else {
return 0;
}
} else {
if (r > p) {
swap(nums + rs, nums + pos);
return rs;
} else {
return 0;
}
}
}
}
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
堆排序Heapsort的Java和C代码的更多相关文章
- 数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)
堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排 ...
- 正则表达式学习笔记(附:Java版示例代码)
具体学习推荐:正则表达式30分钟入门教程 . 除换行符以外的任意字符\w word,正常字符,可以当做变量名的,字母.数字.下划线.汉字\s space,空白符 ...
- java俄罗斯方块游戏代码
java俄罗斯方块游戏代码: package com; import java.awt.Color; import java.awt.Graphics; import java.awt.event.K ...
- java常用用代码
/** *Java获取IP代码 */ import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.ev ...
- java学用代码
/** *Java获取IP代码 */ import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.ev ...
- 分享非常有用的Java程序(关键代码)(七)---抓屏程序
原文:分享非常有用的Java程序(关键代码)(七)---抓屏程序 import java.awt.Dimension; import java.awt.Rectangle; import java.a ...
- 分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要)
原文:分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要) XML文件 <?xml version="1.0"?> <student ...
- 分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map
原文:分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map import java.util.Map; import org.apache.commons.lang.Ar ...
- 分享非常有用的Java程序 (关键代码)(四)---动态改变数组的大小
原文:分享非常有用的Java程序 (关键代码)(四)---动态改变数组的大小 /** * Reallocates an array with a new size, and copies the co ...
随机推荐
- 【索引】Oracle之不可见索引和虚拟索引的比对
[索引]Oracle之不可见索引和虚拟索引的比对 Oracle之不可见索引 :http://blog.itpub.net/26736162/viewspace-2124044/ Oracle之虚 ...
- CyclicBarrier 使用详解
原文:https://www.jianshu.com/p/333fd8faa56e 1. CyclicBarrier 是什么? 从字面上的意思可以知道,这个类的中文意思是“循环栅栏”.大概的意思就是一 ...
- beta版本——第五次冲刺
第五次冲刺 (1)SCRUM部分☁️ 成员描述: 姓名 李星晨 完成了哪个任务 界面优化 花了多少时间 2h 还剩余多少时间 2h 遇到什么困难 没有 这两天解决的进度 2/2 后续两天的计划 完成文 ...
- Yii集成PHPWord
一.安装 1.下载composer curl -sS https://getcomposer.org/installer | php 将composer.phar文件移动到bin目录以便全局使用com ...
- 在linux中使用Sqlplus命令登录MySQL,查看表并设置行数和宽度,使其正常显示
在linux中使用sqlplus命令进入MySQL,设置行数和行宽 1) 查看目前的pagesize,默认是14: 1. show pagesize; 2. set pa ...
- django-发送文件
客户端授权密码”,勾选“开启”,弹出新窗口填写手机验证码. settings.py配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBac ...
- 基于Helm和Operator的K8S应用管理
https://blog.csdn.net/RancherLabs/article/details/79483013 大家好,今天我们分享的内容是基于Helm和Operator的K8S应用管理. 我们 ...
- LeetCode 449. Serialize and Deserialize BST
原题链接在这里:https://leetcode.com/problems/serialize-and-deserialize-bst/description/ 题目: Serialization i ...
- Greenplum常用的gp_toolkit & pg_catalog监控语句
gp_toolkit 说明 Greenplum数据库提供了一个名为gp_tooikit的管理schema,该schema下有关于查询系统目录,日志文件, 用户创建(databases,schema,t ...
- c++ 将float 类型转换成string 类型
string Convert(float Num) { ostringstream oss; oss<<Num; string str(oss.str()); return str; }