您的位置:首页 > 编程语言 > Java开发

常用算法之堆排原理介绍与java实践

2016-04-09 21:04 561 查看
堆排是一种常见的排序算法,空间复杂度为o(1),时间复杂度是o(nlogn)。

原理介绍:

思想类似与冒泡排序、选择排序。逐步求取每个子树的最大值,直至最大值到达最顶层索引值为0的堆顶。

堆排是利用堆进行排序的方法。可分为大堆和小堆,即数值越大,所处堆的层级越靠上。

其中,堆在计算机中是一种数据结构,再细致点讲,是一个完全二叉树。

如果堆的底层用数组存储数据的话,则存在如下性质:

1、某元素序号为i,则其左右子树的序号分别为2i+1, 2i+2。

2、父节点的序号为(i-1)/2取整数。

算法步骤:

1、根据数组构建堆,此时,堆无序。构建堆的方法很简单:思想类似于广度优先。具体见后文源代码。

2、根据数组,构建有序堆(大堆或者小堆):从最后一个索引值开始,循环排序,并整理。具体见后文源代码。

3、构建出有序堆后,堆顶即是最值(最大或最小),将堆顶元素(即索引值为0)与堆内最大索引值交换。

4、忽略最大值元素后,对剩下元素组成的数组,循环步骤2、3,直到遍历完所有元素。

java源代码如下:

public class HeapSort {

public static void main(String[] args) {
int[] data9 = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };
int[] data6 = new int[] { 3, 1, 5, 6, 9, 10 };
print(data9);
System.out.println("排序开始.........");
heapSort(data9);
System.out.println("排序后的数组:");
print(data9);
}

public static void swap(int[] data, int i, int j) {
if (i == j) {
return;
}
data[i] = data[i] + data[j];
data[j] = data[i] - data[j];
data[i] = data[i] - data[j];
}

public static void heapSort(int[] data) {
for (int i = 0; i < data.length; i++) {
createMaxdHeap(data, data.length - 1 - i); //从最后一个元素开始
swap(data, 0, data.length - 1 - i);
print(data);
}
}

public static void createMaxdHeap(int[] data, int lastIndex) {
for (int i = (lastIndex - 1) / 2; i >= 0; i--) { // (lastIndex - 1) / 2 : 表示父节点索引
int k = i; // 保存当前正在判断的节点
while (2 * k + 1 <= lastIndex) { // 若当前节点的子节点存在
int biggerIndex = 2 * k + 1; // biggerIndex总是记录较大节点的值,先赋值为当前判断节点的左子节点
if (biggerIndex < lastIndex) { // 若右子节点存在,否则此时biggerIndex应该等于 lastIndex
if (data[biggerIndex] < data[biggerIndex + 1]) { // 若右子节点值比左子节点值大,则biggerIndex记录的是右子节点的值
biggerIndex++;
}
}

if (data[k] < data[biggerIndex]) { // 若当前节点值比子节点最大值小,则交换2者得值,交换后将biggerIndex值赋值给k
swap(data, k, biggerIndex);
k = biggerIndex;
} else {
break;
}
}
}
}

public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
System.out.println();
}

}


运行结果如下:
5 3
6 2 1
9 4
8 7

排序开始.........

3 8 6
7 1
5 4 2
9

2 7 6
3 1
5 4 8
9

4 3 6
2 1
5 7 8
9

4 3 5
2 1
6 7 8
9

1 3 4
2 5
6 7 8
9

2 3 1
4 5
6 7 8
9

1 2 3
4 5
6 7 8
9

1 2 3
4 5
6 7 8
9

1 2 3
4 5
6 7 8
9

排序后的数组:

1 2 3
4 5
6 7 8
9

参考文章:

1、http://jingyan.baidu.com/article/ab0b56308e59b3c15afa7d29.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  heap 堆排 基本算法