**基本原理也是选择排序,只是不在使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的数。
PS:排升序要建大堆;排降序要建小堆。**
实现:
//堆排序
public void heapSort(int[] array) {
createHeap(array);
//直接将数组长度减一,下次向下调整对最后一个元素不做处理,heapSize等于0的时候就只有一个元素为排序
for (int heapSize = array.length - 1; heapSize > 0; heapSize–) {
int tmp = array[0];
array[0] = array[heapSize];
array[heapSize] = tmp;
shiftDown(array,heapSize,0);
}
}
private void createHeap(int[] array) {
//第一次减一是得到最后一个元素,在减一是为了找它的双亲结点
for (int i = (array.length -1 - 1) / 2; i >= 0 ; i–) {
shiftDown(array,array.length,i);
}
}
private void shiftDown(int[] array, int size, int index) {
int parent = index;
int child = 2 * parent + 1;
while (child < size) {
if(child + 1 < size && array[child + 1] > array[ child]) {
child ++;
}
if(array[child] > array[parent]) {
int tmp = array[child];
array[child] = array[parent];
array[parent] = tmp;
}else {
break;
}
parent = child;
child = 2 * parent + 1;
}
}
性能分析:
- 时间复杂度
O(NlogN)
- 空间复杂度
O(1)
冒泡排序- 原理(稳定)
在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序。
实现:
//冒泡排序,从前到后
public void bubbleSort(int[] array) {
for (int bound = 0; bound < array.length; bound++) {
//最后一个元素不用排序所以减一,已排好的bound个也不用对其进行比较处理
for (int i = 0; i < array.length -1 -bound; i++) {
if(array[i] > array[i + 1]) {
int tmp = array[i];
array[i] = array[i + 1];
array[i + 1] = tmp;
}
}
}
}
//冒泡排序从后到前
public void bubbleSort1(int[] array) {
for (int bound = 0; bound < array.length; bound++) {
for(int i = array.length - 1; i > bound; i --) {
if(array[i - 1] > array[i]) {
int tmp = array[i];
array[i] = array[i - 1];
array[i - 1] = tmp;
}
}
}
}