今天我们再来讨论一下选择类排序,选择类排序分为:简单排序,树形选择排序和堆排序。但我们主要说的是简单和堆排序两个,因为树形选择排序使用了较多的辅助空间,以及和∞进行多余比较,为弥补树形选择排序的不足之处, J.W.J.Williams 在 1964 年提出了进一步的改进方法,即堆排序.对于我个人而言。。一开始并不是很理解它的算法思想,纠结了许久。在网上查找资料的时候发现这位大神的文章思路十分清晰,而且把创建堆以及堆化数组的算法讲解的十分详细。如果有不明白堆排序思路的,可以先看看这篇文章~堆与堆排序
下面我们先从简单排序算法说起~
1.简单排序算法的基本思想非常简单,即:第一趟,从 n 个元素中找出关键字最小的元素与第一个元素交换;第二趟,在从第二个元素开始的 n-1 个元素中再选出关键字最小的元素与第二个元素交换;如此,第 k 趟,则从第 k 个元素开始的 n-k+1 个元素中选出关键字最小的元素与第 k 个元素交换,直到整个序列按关键字有序。
<strong> public void Selection_Sort(int[] A, int N) { for (int i = 0; i < N; i++) { int Min = i; for (int j = i + 1;j < N;j++){ //找出最小元 if(A[j] < A[Min]) Min = j; } if(Min != i){ //交换位置:将未排序部分的最小元换到有序部分的最后位置 int temp = A[Min]; A[Min] = A[i]; A[i] = temp; } } for(int i = 0 ; i < N; i++){ System.out.print(A[i] + " "); } }</strong>【效率分析】
(因为自己一开始没有写出来。。于是把自己觉得思路清晰的代码Copy过来,供大家学习交流 =。= |||)
<strong>方法1: public class HeapSort { /** * 堆排序,最坏时间复杂度O(nlog2n),平均性能接近于最坏性能。 由于建初始堆所需的比较次数多,故堆不适合记录较少的比较。 * 堆排序为原地不稳定排序 * * @param array */ public void Heap_Sort(int[] A, int N) { for (int i = 1; i < A.length; i++) { makeHeap(A, i); } for (int i = A.length - 1; i > 0; i--) { int temp = A[i]; A[i] = A[0]; A[0] = temp; rebuildHeap(A, i); } for (int i = 0; i < N; i++) { System.out.print(A[i] + " "); } } /** * 堆排序辅助方法---创建堆 * @param array * @param k */ private static void makeHeap(int[] array, int k) { int current = k; while (current > 0 && array[current] > array[(current - 1) / 2]) { int temp = array[current]; array[current] = array[(current - 1) / 2]; array[(current - 1) / 2] = temp; current = (current - 1) / 2; } } /** * 堆排序辅助方法---堆的根元素已删除,末尾元素已移到根位置,开始重建 * @param array * @param size */ private static void rebuildHeap(int[] array, int size) { int currentIndex = 0; int right = currentIndex * 2 + 2; int left = currentIndex * 2 + 1; int maxIndex = currentIndex; boolean isHeap = false; while (!isHeap) { if (left < size && array[currentIndex] < array[left]) { maxIndex = left; } if (right < size && array[maxIndex] < array[right]) { maxIndex = right; } if (currentIndex == maxIndex) { isHeap = true; } else { int temp = array[currentIndex]; array[currentIndex] = array[maxIndex]; array[maxIndex] = temp; currentIndex = maxIndex; right = currentIndex * 2 + 2; left = currentIndex * 2 + 1; } } } public static void main(String[] args) { HeapSort heapSort = new HeapSort(); int[] B = new int[] { 26, 53, 48, 11, 13, 48, 32, 15 }; int N = 8; heapSort.Heap_Sort(B, N); } } 方法2: public class HeapSort2 { public static void main(String[] args) { int[] array = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 }; System.out.println("Before heap:"); ArrayUtils.printArray(array); heapSort(array); System.out.println("After heap sort:"); ArrayUtils.printArray(array); } //建立最大堆 public static void heapSort(int[] array) { if (array == null || array.length <= 1) { return; } buildMaxHeap(array); for (int i = array.length - 1; i >= 1; i--) { ArrayUtils.exchangeElements(array, 0, i); maxHeap(array, i, 0); } } //调整堆 private static void buildMaxHeap(int[] array) { if (array == null || array.length <= 1) { return; } int half = array.length / 2; for (int i = half; i >= 0; i--) { maxHeap(array, array.length, i); } } private static void maxHeap(int[] array, int heapSize, int index) {//最大堆 int left = index * 2 + 1;// 左孩子的下标(如果存在的话) int right = index * 2 + 2;// 右孩子的下标(如果存在的话) int largest = index; if (left < heapSize && array[left] > array[index]) { largest = left; } if (right < heapSize && array[right] > array[largest]) { largest = right; } if (index != largest) { ArrayUtils.exchangeElements(array, index, largest); maxHeap(array, heapSize, largest); } } } class ArrayUtils { public static void printArray(int[] array) { System.out.print("{"); for (int i = 0; i < array.length; i++) { System.out.print(array[i]); if (i < array.length - 1) { System.out.print(", "); } } System.out.println("}"); } public static void exchangeElements(int[] array, int index1, int index2) { int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } }</strong>显然堆排序只需要一个辅助空间,比树形排序的效率更高一些。堆排序在元素较少时由于消耗较多时间在初始建堆上,因此不值得提倡,然而当元素较多时还是很有效的排序算法。
PS:如果大家还想看其他的排序算法~请戳这里 =。=
原文地址:http://blog.csdn.net/qq_21394609/article/details/43924473