问题描述

用基于变治法的堆排序算法对任意一组给定的数据进行排序

2.1 堆排序原理简介

堆可以定义为一颗二叉树,树的节点中包含键(每个节点是一个键),并且满足下面两个条件:

(1)树的形状要求——这颗二叉树是基本完备的(或者简称为完成二叉树),这意味着,树的每一层都是满的,除了最后一层最右边的元素有可能缺位。

(2)父母优势要求,又称为堆特性——每一个节点的键都要大于或等于它子女的键(对于任何孩子节点也要自动满足父母优势要求)。

2.2 变治法原理简介

变治法:首先,在“变”的阶段,出于这一或者那样的原因,把问题的实例变得更容易求解(PS:类似本文求解问题,在排序前先把数组中数进行成堆处理);然后,在第二阶段或者说“治”的阶段,对实例进行求解。

根据我们对问题实例的变换方式,变治思想有3种主要的类型:

(1)变换为同样问题的一个更简单或者更方便的实例——我们称之为实例化简;

(2)变换为同样实例的不同表现——我们称之为改变表现;

(3)变换为另一个问题的实例,这种问题的算法是已知的——我们称之为问题的化简。

package com.liuzhen.heapsort;

public class HeapSort {
/*将array[a]和array[b]、array[c]中最大值进行比较,如果较小则将array[a]与array[b]、array[c]中最大值
进行交换,否则直接返回数组array*/
public static int[] getMaxA(int[] array,int a,int b ,int c){
int temp = 0;
if(array[b] >= array[c]){
if(array[a] < array[b]){
temp = array[a];
array[a] = array[b];
array[b] = temp;
}
}
else{
if(array[a] < array[c]){
temp = array[a];
array[a] = array[c];
array[c] = temp;
}
}
return array;
} //根据堆排序父母优势规则,返回一个给定长度的数组的成堆结果
public static int[] getHeapSort(int[] array , int len){
boolean judge = true;
while(judge){
//根据堆排序父母优先规则,对数组array进行排序
for(int i = 1;i <= len/2;i++){
if((2*i+1) < len)
array = getMaxA(array,i,(2*i),(2*i+1));
if((2*i) == len-1){ //当2*i == len-1时,说明array[i]只有一个左孩子节点a[2*i]
int temp = 0;
if(array[i] < array[2*i]){
temp = array[i];
array[i] = array[2*i];
array[2*i] = temp;
}
}
} //遍历数组array,一旦出现根节点小于其叶子节点时,跳出for循环
int j;
for(j = 1;j < len/2;j++){
if((2*j+1) < len){
if(array[j] < array[2*j])
break;
if(array[j] < array[2*j+1])
break;
}
if((2*j) == len-1){
if(array[j] < array[2*j])
break;
}
} if(j == len/2) //如果j==len/2,说明遍历结果符合堆排序规则,直接结束while循环
judge = false;
}
return array;
} //使用数组成堆,对一个数组元素进行从小到大排序,并返回排序后的结果
public static int[] getResultSort(int[] array , int len){
array = getHeapSort(array , len); //首先对数组进行堆排序处理
int temp = 0; //数组值交换中间变量
int sortLen = len; //排序过程中,需要重新进行堆排序的数组长度,并初始化为array的总长度
while(sortLen > 2){
// for(int i = 1;i < len;i++)
// System.out.print(array[i]+"\t");
// System.out.println();
temp = array[1]; //交换array[0]和array[sortLen-1]的值,即把最大的值放在未排序的数组最后一位
array[1] = array[sortLen-1];
array[sortLen-1] = temp;
sortLen = sortLen - 1; //交换成功后,未排序的数组长度自动减1
array = getHeapSort(array,sortLen); //对未排序的数组,重新进行堆排序
}
return array;
} //初始化一个长度为n的随机数组
public static int[] initArray(int n){
int[] result = new int[n];
result[0] = 0;
for(int i = 1;i < n;i++)
result[i] = (int)(Math.random()*1000); //采用随机函数随机生成0~1000之间的数
return result;
} public static void main(String args[]){
int[] array = {0,1,4,5,3,5,23,45,12,23,34,56,78,23,24,25}; //此处定义数组,对array[1]到array[len-1]进行排序
int len = array.length;
int[] result = getResultSort(array,len);
System.out.println("手动输入数组,使用堆排序,最终排序结果:");
for(int i = 1;i < len;i++){
System.out.print(result[i]+"\t");
} System.out.println();
System.out.println();
int[] oneArray = initArray(1000);
int len1 = 1000;
int[] result1 = getResultSort(oneArray,len1);
System.out.println("系统随机生成的长度为1000的数组(其值均在0~1000之间),使用堆排序,最终排序结果:");
for(int j = 1;j < len1;j++){
System.out.print(result1[j]+"\t");
if(j%15 == 0)
System.out.println();
}
}
}

Java实现堆排序问题(变治法)的更多相关文章

  1. Java中的逆变与协变

    看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); ...

  2. Java中的逆变与协变(转)

    看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); ...

  3. Java泛型的逆变

    在上篇<Java泛型的协变>这篇文章中遗留以下问题——协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码清 ...

  4. Java中的逆变与协变 专题

    结论先行: PECS总结: 要从泛型类取数据时,用extends: 协变 要往泛型类写数据时,用super: 逆变 既要取又要写,就不用通配符(即extends与super都不用) 不变 List&l ...

  5. [改善Java代码]覆写变长方法也循规蹈矩

    建议6:覆写变长方法也循规蹈矩 在Java中,子类覆写父类中的方法很常见,这样做既可以修正Bug也可以提供扩展的业务功能支持,同时还符合开闭原则(Open-Closed Principle),我们来看 ...

  6. Java实现堆排序

    import java.util.Scanner; /*堆是一种数据结构,类似于一棵完整的二叉树. * 思想:堆的根节点值最大(最小),将无序序列调整成一个堆,就能找出这个序列的最大值(最小值),将找 ...

  7. 蓝桥杯比赛java 练习《立方变自身》

    立方变自身 观察下面的现象,某个数字的立方,按位累加仍然等于自身.1^3 = 1 8^3  = 512    5+1+2=817^3 = 4913   4+9+1+3=17... 请你计算包括1,8, ...

  8. Java实现堆排序和计数排序

    堆排序代码: 思想:每次都取堆顶的元素,将其放在序列最后面,然后将剩余的元素重新调整为最小堆,依次类推,最终得到排序的序列. import java.util.Arrays; /** * 思路:首先要 ...

  9. Java中的逆变与协变 很直接不饶弯的讲出来了

    ```java 协变 extends只能new 辈分比自己低的家伙 List<? extends Number> list001 = new ArrayList<Integer> ...

随机推荐

  1. js理论-函数中的Arguments对象

    详情参考:https://github.com/mqyqingfeng/Blog/issues/14 如果: arguments和实参的关系,以及arguments的属性 附上代码和注解 functi ...

  2. 【clear linux】intel clear linux 电源状态命令

    # 重启系统 $ sudo systemctl reboot # 关闭系统,切断电源 $ sudo systemctl poweroff # CPU停止工作 $ sudo systemctl halt ...

  3. mfw

    0x01 可能为git泄露 git泄露 githack下载源码 index.php <?php if (isset($_GET['page'])) { $page = $_GET['page'] ...

  4. Atcoder Beginner Contest 167

    赛场实况: 训练反思: A题签到不说了,B题第一眼没看清楚数据范围,写了一堆然后仔细一看1e12果断不能暴力..立马换了一个写法,连交2发wa(细节啊细节!!),C题看了半天英语没看懂说了什么,拿翻译 ...

  5. python mysql数据库基本操作方法

    实现:使用Python实现用户登录,如果用户存在(数据库表中存在)则登录成功(假设该用户已在数据库中) import pymysql username = input('输入用户名:').strip( ...

  6. 数据源管理 | OLAP查询引擎,ClickHouse集群化管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.列式库简介 ClickHouse是俄罗斯的Yandex公司于2016年开源的列式存储数据库(DBMS),主要用于OLAP在线分析处理查询, ...

  7. HTML标签和属性一

    一.web基础知识 html,专门指网页技术 HTML5,大前端技术(网页,app,桌面程序,数据可视化,VR....) 网页(pc,pad,phone) app  wx  服务器 数据库 HTML5 ...

  8. ol,li,ul,dl,dt,dd

    块级元素div尽量少用,其实和table一样,嵌套越少越好,它也是会影响速度的! ol 有序列表. <ol> <li>……</li> <li>……< ...

  9. ubuntu下安装perl GD模块

    依次执行: sudo apt-get install libgd2-xpm-dev sudo perl -MCPAN -e shell install Bundle::CPAN install GD: ...

  10. 【linux】linux下java环境安装

    1:下载jdk的包,通过ftp传到服务器 2:解压 tar zxvf jdk-8u181-linux-x64.tar.gz 3:环境配置 编辑配置文件: vim /etc/profile 在文件下插入 ...