堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。
public class stackSort {
static int[] datas = new int[] { 45, 651, 54, 8, 98, 45, 1,6, 48, 456, 1, 5615, 6 };
// 堆排序主要分为两个过程,1、建堆。2、选择 交换。
public static void main(String[] args) {
// TODO Auto-generated method stub
sort(datas);
for (int data : datas) {
System.out.println(data);
}
}
public static void sort(int[] datas) {
int position = datas.length - 1;// 默认长度大于0,忽略长度<=0,或者为空的情况
for (int i = position; i > 0; i--) {
// 1,建堆
buildStack(datas, i);
// 2、交换
int temp = datas[0];
datas[0] = datas[i];
datas[i] = temp;
}
}
/**
* 建堆
*
* @param datas
* @param len
*/
public static void buildStack(int[] datas, int lastIndex) {
int i = (lastIndex - 1) / 2;
for (; i >= 0; i--) {// 对前二分之一的节点进行建堆
int k = i;// 记录当前节点角标
while (2 * k + 1 <= lastIndex) {// 有子结点
int biggerIndex = 2 * k + 1;
if (biggerIndex < lastIndex) {// <表示有右子结点,
if (datas[biggerIndex + 1] > datas[biggerIndex]) {
biggerIndex++;
}
}
if (datas[biggerIndex] > datas[k]) {
// 交换
datas[biggerIndex] = datas[biggerIndex] + datas[k];
datas[k] = datas[biggerIndex] - datas[k];
datas[biggerIndex] = datas[biggerIndex] - datas[k];
k = biggerIndex;
} else {
break;
}
}
}
}
}
//堆排序最主要的是建堆的过程,这是建堆的核心代码。
//1、首先记录当前节点的角标k,在当前节点和两个子结点(如果存在)中选择最大的值,放在当前节点。
//2、k指向被交换的子结点,(由于交换,被交换的子结点的大(小)顶堆的结构配破坏,需要重复1,2操作过程)
int k = i;// 记录当前节点角标,2 * k + 1表示左子结点
while (2 * k + 1 <= lastIndex) {// 有左子结点
int biggerIndex = 2 * k + 1;//记录左子结点的角标
if (biggerIndex < lastIndex) {// 这里主要不带等号,<:表示有右子结点,
if (datas[biggerIndex + 1] > datas[biggerIndex]) {//找到大的子结点的序号
biggerIndex++;
}
}
if (datas[biggerIndex] > datas[k]) {//需要交换
// 交换
datas[biggerIndex] = datas[biggerIndex] + datas[k];
datas[k] = datas[biggerIndex] - datas[k];
datas[biggerIndex] = datas[biggerIndex] - datas[k];
k = biggerIndex;//k指向被破坏的子结点,重复上述过程
} else {//不需要交换则直接退出
break;
}
}