排序算法 | 最佳时间复杂度 | 平均时间复杂度 | 最坏时间复杂度 | 稳定性 | 空间复杂度 |
插入排序 | O(n) | O(n^2) | O(n^2) | 稳定 | O(1) |
快速排序 | O(nlogn) | O(nlogn) | O(n^2) | 不稳定 | O(logn) |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | 不稳定 | O(1) |
冒泡排序 | O(n) | O(n^2) | O(n^2) | 稳定 | O(1) |
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | 稳定 | O(n) |
直接插入排序
把待排序的记录按其值的大小逐一插入到一个已排好序的有序序列中,直到所有的记录插入完为止。
public void insertSort(int[] array){
for(int i = 1; i < array.length; i++){
int temp = array[i];
int j = i;
while(j - 1 >= 0 && array[j - 1] > temp){
array[j] = array[j - 1];
j--;
}
array[j] = temp;
}
}
快速排序
任取待排序元素序列中的某元素作为基准值,按照该基准值将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直至所有元素都排列在相应位置上为止。
class Solution{
public void quickSort(int[] array, int start, int end){
if(start >= end){
return;
}
int pivot = partition(array, start, end);
quickSort(array, start, pivot - 1);
quickSort(array, pivot + 1, end);
}
public int partition(int[] array, int left, int right){
int temp = array[left];
while(left < right){
while(left < right && array[right] >= temp){
right--;
}
array[left] = array[right];
while(left < right && array[left] <= temp){
left++;
}
array[right] = array[left];
}
array[left] = temp;
return left;
}
}
堆排序
首先将数组元素建成大小为n的大顶堆,堆顶(数组第一个元素)是所有元素中的最大值,将堆顶元素和数组最后一个元素进行交换,再将除了最后一个数的n-1个元素 建立成大顶堆,再将最大元素和数组倒数第二个元素进行交换,重复直至堆大小减为1。
class Solution{
public void heapSort(int[] array) {
//1、大根堆 O(N)
createHeap(array);
//2、排序O(n*logn)
for(int i = array.length - 1; i >= 1; ) {
swap(array, 0, i); // 把堆顶元素(当前最大)交换到数组末尾
i--; // 逐步减少堆有序的部分
shiftDown(array, 0, i); // 下标0位置下沉操作,使得区间 [0, i] 堆有序
}
}
//创建大根堆
private void createHeap(int[] array) {
for (int parent = (array.length - 1) / 2; parent >= 0; parent--) {
shiftDown(array, parent, array.length - 1);
}
}
//向下调整
private void shiftDown(int[] array, int parent, int len) {
int child = 2 * parent + 1;
while (child <= len) {
if(child + 1 <= len && array[child] < array[child + 1]) {
child++; //它一定保存的是左右孩子的最大值的下标
}
if(array[child] > array[parent]) {
swap(array, child, parent);
parent = child;
child = 2 * parent + 1;
}else {
break;
}
}
}
public void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
冒泡排序
它重复的遍历数组,每次比较两个元素,按照规定的排序规则将其排序,当数组有序时,排序结束。
class Solution{
public static void bubbleSort(int[] array) {
for(int i = array.length - 1; i >= 0; i--) {
boolean flag = false;
for(int j = 0; j < i; j++) {
if(array[j] > array[j + 1]) {
swap(array, j, j + 1);
flag = true;
}
}
if(flag == false) {
break;
}
}
}
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
归并排序
首先让数组中的每一个数单独成为长度为1的区间,然后两两一组有序合并,得到长度为2的有序区间,依次进行,直到合成整个区间。
class Solution{
private static void mergeSort(int[] array,int left,int right) {
if(left >= right) {
return;
}
int mid = (left + right) >>> 1;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, right, mid);
}
//合并函数
private static void merge(int[] array, int left, int right, int mid) {
int[] temp = new int[right - left + 1];
int index = 0;
int i = left;
int j = mid + 1;
while (i <= mid && j <= right) {
if(array[i] <= array[j]) {
temp[index++] = array[i++];
}else {
temp[index++] = array[j++];
}
}
while (i <= mid) {
temp[index++] = array[i++];
}
while (j <= right) {
temp[index++] = array[j++];
}
for(int k = 0; k < index; k++) {
array[k + left] = temp[k];
}
}
}