Java实现八大排序算法,以及这些排序算法时间复杂度、空间复杂度、稳定性等比较
冒泡排序
public void sort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int temp = 0;
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
选择排序
public void sort(int[] arr) {
int min = -1;
int temp = -1;
for (int i = 0; i < arr.length; i++) {
min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
if (min != i) {
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
插入排序
public static void sort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; ++i) {
int value = arr[i];
int j = 0;//插入的位置
for (j = i - 1; j >= 0; j--) {
if (arr[j] > value) {
arr[j + 1] = arr[j];//移动数据
} else {
break;
}
}
arr[j + 1] = value; //插入数据
}
}
希尔排序
public static void shellSort(int[] arr) {
int length = arr.length;
int gap = 1;
while (gap < length) {
gap = gap * 3 + 1;
}
while (gap > 0) {
for (int i = gap; i < length; i++) {
int value = arr[i];
int index = -1;
int j = i - gap;
for (; j >= 0; j = j - gap) {
if (value < arr[j]) {
arr[j + gap] = arr[j];
index = j;
} else {
break;
}
}
arr[j + gap] = value;
}
gap = gap / 3;
}
}
归并排序
public void mergeSort(int[] arr, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
// 分治
mergeSort(arr, start, mid);
// 分治
mergeSort(arr, mid + 1, end);
// 归并
merge(arr, start, mid, end);
}
}
public void merge(int[] arr, int start, int mid, int end) {
int[] newArr = new int[end - start + 1];
int index = 0, i = start, j = mid + 1;
while (i <= mid && j <= end) {
newArr[index++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
}
while (i <= mid) {
newArr[index++] = arr[i++];
}
while (j <= end) {
newArr[index++] = arr[j++];
}
index = 0;
while (start <= end) {
arr[start++] = newArr[index++];
}
}
快速排序
public void quickSort(int[] arr, int start, int end) {
if (start < end) {
int pivotPos = partition(arr, start, end);
quickSort(arr, start, pivotPos - 1);
quickSort(arr, pivotPos + 1, end);
}
}
public int partition(int[] arr, int start, int end) {
int pivot = arr[start];
while (start < end) {
while (start < end && arr[end] >= pivot) {
end--;
}
arr[start] = arr[end];
while (start < end && arr[start] <= pivot) {
start++;
}
arr[end] = arr[start];
}
arr[start] = pivot;
return start;
}
大根堆排序(或者小根堆排序)
// 主函数
public static void main(String[] args) {
int[] arr = new int[]{5,4,8,3,6,2,1,7};
buildMaxHeap(arr);
int length = arr.length;
for (int i = length - 1; i >= 0; i--) {
// 每一趟形成一个大根堆,然后将根节点排出,将根节点排出得方法是每一趟置换最后一个元素和第一个元素,其余结点继续构建大根堆,以此循环
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
length--;
sink(arr, 0, length);
}
}
// 构建大根堆
public static void buildMaxHeap(int[] arr) {
for (int i = arr.length / 2; i >= 0; i--) {
sink(arr, i, arr.length);
}
}
// 把大的元素向上浮动,小的元素向下沉
public static void sink(int[] arr, int index, int length) {
int leftChild = 2 * index + 1;
int rightChild = 2 * index + 2;
int present = index;
if (leftChild < length && arr[leftChild] > arr[present]) {
present = leftChild;
}
if (rightChild < length && arr[rightChild] > arr[present]) {
present = rightChild;
}
if (present != index) {
int temp = arr[present];
arr[present] = arr[index];
arr[index] = temp;
// 关键步骤,每次交换之后,得确保子树也是大根堆,因此要继续向下沉
sink(arr, present, length);
}
}
基数排序
基数排序的思想:即桶排序。先按照每个数的各位排序,并放在0-9的桶中,排成一个新的序列;然后再将新的序列按照十位排序,并放入桶中,再形成一个新的序列。然后依次排序百位,千位,直到所有数字位数都用尽,最终序列就是排好序的序列。
public void bucketSort(int[] arr) {
// 记录最大值
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] >= max) {
max = arr[i];
}
}
// 构建10个桶,0-9用来装数字
ArrayList<ArrayList<Integer>> list = new ArrayList();
for (int i = 0; i < 10; i++) {
list.add(new ArrayList());
}
// 当前排序位置
int location = 1;
while (true) {
int dd = (int)Math.pow(10, location - 1);
if (dd > max) {
break;
}
// 数据入桶
for (int i = 0; i < arr.length; i++) {
int index = (arr[i] / dd) % 10;
list.get(index).add(arr[i]);
}
// 写回数组
int k = 0;
for (int i = 0; i < 10; i++) {
int size = list.get(i).size();
for (int ii = 0; ii < size; ii++) {
arr[k++] = list.get(i).get(ii);
}
list.get(i).clear();
}
location++;
}
}
=====================================================================
八大排序算法比较:
=====================================================================
排序名称 | 最好情况 | 平均情况 | 最坏情况 | 空间复杂度 | 是否稳定 |
---|---|---|---|---|---|
插入排序 | O(n) | O(n^2) | O(n^2) | O(1) | 是 |
冒泡排序 | O(n) | O(n^2) | O(n^2) | O(1) | 是 |
选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 否 |
希尔排序 | O(1) | 否 | |||
快速排序 | O(nlog2n) | O(nlog2n) | O(n^2) | O(nlog2n) | 否 |
堆排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(1) | 否 |
归并排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(n) | 是 |
基数排序 | O(d(n + r)) | O(d(n + r)) | O(d(n + r)) | O® | 是 |