package test2018.test08;
import java.util.Random;
/**
* Filename: Class7Duipaixu.java Description: 堆排序:第一步,建堆,保证所有父节点大于子节点的值
* 第二步,取值:把根节点移到后面,然后移位
*
* @author: guzhangyan
* @date: 2018年8月7日 下午4:54:04
*/
public class Class7Duipaixu {
public static void main(String[] args) {
long stratTime = System.currentTimeMillis();
int[] shuZu = new int[100000000];
Random random = new Random();
for (int i = 0; i < shuZu.length; i++) {
shuZu[i] = random.nextInt(100);
}
jianDui(shuZu, 0);
/*
* for (int i = 1; 2 * i + 2 < shuZu.length; i++) {// 检验是否建堆成功 if (shuZu[i] -
* shuZu[2 * i + 2] < 0) { System.out.println(i); } if (shuZu[i] - shuZu[2 * i +
* 1] < 0) { System.out.println(i); } }
*/
// System.out.println(Arrays.toString(shuZu));
for (int i = 0; i < shuZu.length - 1; i++) {
yiwei(shuZu, shuZu.length - 1 - i);
}
// System.out.println(Arrays.toString(shuZu));
/*
* for (int i = 1; i < shuZu.length; i++) { if (shuZu[i] - shuZu[i - 1] < 0) {
* System.out.println(i); } }
*/
long endTime = System.currentTimeMillis();
System.out.println("堆排序时间:" + (endTime - stratTime));
}
private static void yiwei(int[] shuZu, int endKey) {
if (endKey == 0) {
return;
}
int top = shuZu[0];
int endNum = shuZu[endKey];
int lastYiWeiKey = getYiWeiKey(shuZu, 0, endKey + 1, endNum);
shuZu[lastYiWeiKey] = shuZu[endKey];
shuZu[endKey] = top;
/*
* for (int i = 1; 2 * i + 2 < endKey + 1; i++) {// 检验是否建堆成功 if (shuZu[i] -
* shuZu[2 * i + 2] < 0) { System.out.println(i + "--" + shuZu[i] + ":" +
* shuZu[2 * i + 2]); } if (shuZu[i] - shuZu[2 * i + 1] < 0) {
* System.out.println(i + "--" + shuZu[i] + ":" + shuZu[2 * i + 1]); } }
*/
// System.out.println(endKey + "::" + Arrays.toString(shuZu));
}
// 此方法不仅是把子节点较大数移到父节点,还判断最后一个数字该去哪
private static int getYiWeiKey(int[] shuZu, int i, int length, int endNum) {
int leftKey = 2 * i + 1;
int rightKey = 2 * i + 2;
if (leftKey >= length) {
return i;
}
int leftCode = shuZu[leftKey];
if (rightKey >= length) {
if (leftCode < endNum) {
return i;
}
shuZu[i] = leftCode;
return getYiWeiKey(shuZu, leftKey, length, endNum);
}
int rightCode = shuZu[rightKey];
if (rightCode > leftCode) {
if (rightCode < endNum) {
return i;
}
shuZu[i] = rightCode;
return getYiWeiKey(shuZu, rightKey, length, endNum);
} else {
if (leftCode < endNum) {
return i;
}
shuZu[i] = leftCode;
return getYiWeiKey(shuZu, leftKey, length, endNum);
}
}
/**
* @param shuZu
* @param i
* @return
* @author: guzhangyan
* @version:2018年8月7日 下午8:00:20 建堆
*/
private static int jianDui(int[] shuZu, int i) {
int leftKey = 2 * i + 1;
int rightKey = 2 * i + 2;
int parentCode = shuZu[i];
if (leftKey >= shuZu.length) {
return parentCode;
}
int leftCode = jianDui(shuZu, leftKey);
if (rightKey >= shuZu.length) {
if (leftCode > parentCode) {
shuZu[i] = leftCode;
shuZu[leftKey] = parentCode;
parentCode = shuZu[i];
jianDui(shuZu, leftKey);
}
return shuZu[i];
}
int rightCode = jianDui(shuZu, rightKey);
if (rightCode > parentCode && rightCode >= leftCode) {
shuZu[i] = rightCode;
shuZu[rightKey] = parentCode;
jianDui(shuZu, rightKey);
} else if (leftCode > parentCode) {
shuZu[i] = leftCode;
shuZu[leftKey] = parentCode;
parentCode = shuZu[i];
jianDui(shuZu, leftKey);
}
return shuZu[i];
}
}
一亿条数据的时间为17.620秒。建堆时间为7.043秒。