Java排序算法9:堆排序
2014-04-13 20:25
211 查看
一.思想:
先将初始序列构造成一个大根堆(或者小根堆),此堆为初始无序区。再将最大记录R[1]与无序区的最后一个记录R
交换,由此可以得到新的无序区R[1....n-1]和有序区R
。由于交换之后新的根R[1]可能不满足大根堆的性质,故将当前无序区R[1...n-1]再次调整为堆,然后再次将R[1]与R[n-1]交换,依次类推。
二.图解:
给定一个整形数组num[]={16,7,3,20,17,8},对其进行堆排序。首先根据该数组元素构建一个完全二叉树,得到
然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:
这样就得到了初始堆。
即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
此时3位于堆顶不满堆的性质,则需调整继续调整
这样整个区间便已经有序了。
三.实现代码:
四.复杂度和应用:
时间复杂度:O(nlog2n) 空间复杂度:O(1)。 是不稳定的算法。
应用:也适用于海量的数据。
五.参考资料:
1.百度百科-堆排序:http://baike.baidu.com/view/157305.htm?fr=wordsearch
2.追竹的博客:http://blog.csdn.net/apei830/article/details/6584645
3.海子的博客园:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
六:相关排序代码下载:
包含(冒泡排序,桶排序,堆排序,插入排序,归并排序,快速排序,基数排序,选择排序,希尔排序)
免积分下载地址:http://download.csdn.net/detail/u014077165/7185895
先将初始序列构造成一个大根堆(或者小根堆),此堆为初始无序区。再将最大记录R[1]与无序区的最后一个记录R
交换,由此可以得到新的无序区R[1....n-1]和有序区R
。由于交换之后新的根R[1]可能不满足大根堆的性质,故将当前无序区R[1...n-1]再次调整为堆,然后再次将R[1]与R[n-1]交换,依次类推。
二.图解:
给定一个整形数组num[]={16,7,3,20,17,8},对其进行堆排序。首先根据该数组元素构建一个完全二叉树,得到
然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:
这样就得到了初始堆。
即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
此时3位于堆顶不满堆的性质,则需调整继续调整
这样整个区间便已经有序了。
三.实现代码:
public class HeapSort { public static void main(String[] args) { int[] data5 = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 }; print(data5); heapSort(data5); System.out.println("排序后的数组:"); print(data5); } 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); } } public static void createMaxdHeap(int[] data, int lastIndex) { for (int i = (lastIndex - 1) / 2; i >= 0; i--) { // 保存当前正在判断的节点 int k = i; // 若当前节点的子节点存在 while (2 * k + 1 <= lastIndex) { // biggerIndex总是记录较大节点的值,先赋值为当前判断节点的左子节点 int biggerIndex = 2 * k + 1; 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(); } }
四.复杂度和应用:
时间复杂度:O(nlog2n) 空间复杂度:O(1)。 是不稳定的算法。
应用:也适用于海量的数据。
五.参考资料:
1.百度百科-堆排序:http://baike.baidu.com/view/157305.htm?fr=wordsearch
2.追竹的博客:http://blog.csdn.net/apei830/article/details/6584645
3.海子的博客园:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
六:相关排序代码下载:
包含(冒泡排序,桶排序,堆排序,插入排序,归并排序,快速排序,基数排序,选择排序,希尔排序)
免积分下载地址:http://download.csdn.net/detail/u014077165/7185895
相关文章推荐
- java排序算法之堆排序
- java排序算法 堆排序
- Java排序算法 堆排序
- Java排序算法 堆排序
- Java排序算法(三):堆排序 .
- 算法相关——Java排序算法之堆排序(七)
- Java排序算法(三):堆排序
- Java排序算法(二)--堆排序(HeapSort)
- Java排序算法——堆排序
- java排序算法(一):堆排序
- Java排序算法--建立堆和堆排序(转)
- Java排序算法之堆排序
- Java排序算法(三):堆排序
- Java排序算法--建立堆和堆排序(练习)
- Java排序算法 堆排序
- Java排序算法总结(六):堆排序
- Java 堆排序
- 最小/大堆的操作及堆排序
- JAVA排序算法---快速排序
- JAVA排序算法---归并排序