冒泡、选择、堆排序
目录
学习大纲
10大排序算法
冒泡排序(Bubble Sort)
- 执行流程(统一以升序为例子)
- ①从头开始比较每一对相邻元素,如果第1个比第2个大,就交换它们的位置
- 执行完一轮后,最末尾那个元素就是最大的元素
- ②忽略①中曾经找到的最大元素,重复执行步骤①,直到全部元素有序
冒泡排序优化1
- 只针对有序有优化效果。
冒泡排序优化2
- 如果序列尾部已经局部有序,可以记录最后1次交换的位置,减少比较次数
排序算法的稳定性(Stability)
原地算法(In-place Algorithm)
选择排序(Selection Sort)
堆排序(Heap Sort)
/** * 堆排序 */ public class HeapSort<T extends Comparable<T>> extends Sort<T> { private int heapSize; // 堆大小 @Override protected void sort() { // 原地建堆(自下而上的下滤) heapSize = array.length; for (int i = (heapSize >> 1) - 1; i >= 0; i--) { siftDown(i); } while (heapSize > 1) { // 交换堆顶元素和尾部元素 swap(0, --heapSize); // 对0位置进行siftDown(恢复堆的性质) siftDown(0); } } private void siftDown(int index) { T element = array[index]; int half = heapSize >> 1; while (index < half) { // index必须是非叶子节点 // 默认是左边跟父节点比 int childIndex = (index << 1) + 1; T child = array[childIndex]; int rightIndex = childIndex + 1; // 右子节点要存在, 并且比左子节点大 if (rightIndex < heapSize && cmp(array[rightIndex], child) > 0) { child = array[childIndex = rightIndex]; } // 大于等于子节点 if (cmp(element, child) >= 0) break; array[index] = child; index = childIndex; } array[index] = element; } }