一、排序算法的介绍
二、算法的时间复杂度
2.1 基本介绍
2.2 时间频度
2.3 时间复杂度的表示
2.4 算法的平均时间复杂度和最坏时间复杂度
三、算法的空间复杂度
四、排序算法
4.1 交换排序
4.1.1 冒泡排序
package com.gyh.sort;
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] nums = {2, 84, 17, 291, 92, 17, 817, 17};
sort(nums, true);
Arrays.stream(nums).forEach(System.out::println);
}
private static void sort(int[] nums, boolean ascending) {
int temp;
boolean flag;
for (int i = 0; i < nums.length - 1; i++) {
flag = true;
for (int j = 0; j < nums.length - 1 - i; j++) {
if (ascending) {
if (nums[j] > nums[j + 1]) {
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
if (flag) flag = false;
}
} else {
if (nums[j] < nums[j + 1]) {
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
if (flag) flag = false;
}
}
}
if (flag) {
return;
}
}
}
}
4.1.2 快速排序
package com.gyh.sort;
import java.util.Arrays;
public class QuickSort2 implements Sort {
public static void main(String[] args) {
int[] nums = {2, 1, 17, 291, 92, 17, 817, 17};
new QuickSort2().sort(nums, false);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
sort(nums, 0, nums.length - 1, ascending);
}
private void sort(int[] nums, int low, int high, boolean ascending) {
int pivot = nums[low];
int l = low;
int h = high;
while (l < h) {
while (l < h && (ascending ? nums[h] >= pivot : nums[h] <= pivot)) {
h--;
}
nums[l] = nums[h];
while (l < h && (ascending ? nums[l] <= pivot : nums[l] >= pivot)) l++;
nums[h] = nums[l];
}
nums[l] = pivot;
if (l - 1 > low) {
sort(nums, low, l - 1, ascending);
}
if (l + 1 < high) {
sort(nums, l + 1, high, ascending);
}
}
}
package com.gyh.sort;
import java.util.Arrays;
public class QuickSort implements Sort {
public static void main(String[] args) {
int[] nums = new int[11];
for (int i = 0; i < nums.length; i++) {
nums[i] = i + 1;
}
nums[1] = 9;
new QuickSort().sort(nums, true);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
sort(nums, 0, nums.length - 1, ascending);
}
private void sort(int[] nums, int left, int right, boolean ascending) {
int l = left;
int r = right;
int temp;
int pivot = nums[(left + right) / 2];
while (l < r) {
while (ascending ? nums[l] < pivot : nums[l] > pivot) {
l++;
}
while (ascending ? nums[r] > pivot : nums[r] < pivot) {
r--;
}
if (l >= r) {
break;
}
temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
if (nums[l] == pivot) {
r--;
}
if (nums[r] == pivot) {
l++;
}
}
if (l == r) {
l += 1;
r -= 1;
}
if (left < r) {
sort(nums, left, r, ascending);
}
if (right > l) {
sort(nums, l, right, ascending);
}
}
}
4.2 选择排序
4.2.1 简单选择排序
package com.gyh.sort;
import java.util.Arrays;
public class SimpleSelectSort implements Sort {
public static void main(String[] args) {
int[] nums = {101, 34, 119, 1};
new SimpleSelectSort().sort(nums, false);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
int index;
int temp;
for (int i = 0; i < nums.length - 1; i++) {
index = i;
for (int j = i + 1; j < nums.length; j++) {
if (ascending) {
if (nums[j] < nums[index]) {
index = j;
}
} else {
if (nums[j] > nums[index]) {
index = j;
}
}
}
if (index != i) {
temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
}
}
}
}
4.2.2 堆排序
package com.gyh.sort;
import java.util.Arrays;
public class HeapSort implements Sort {
public static void main(String[] args) {
int[] nums = {2, 1, 17, 291, 92, 17, 817, 17};
new HeapSort().sort(nums, true);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
if (nums == null || nums.length <= 1) {
return;
}
createHeap(nums, ascending);
int temp;
for (int i = nums.length - 1; i > 0; i--) {
temp = nums[i];
nums[i] = nums[0];
nums[0] = temp;
heapAdjust(nums, 0, i - 1, ascending);
}
}
private void createHeap(int[] arr, boolean ascending) {
if (arr == null || arr.length <= 0) {
return;
}
int n = arr.length / 2 - 1;
for (int i = n; i >= 0; i--) {
heapAdjust(arr, i, arr.length - 1, ascending);
}
}
private void heapAdjust(int[] arr, int org, int dis, boolean ascending) {
int r = arr[org];
for (int i = 2 * org + 1; i <= dis; i = i * 2 + 1) {
if (i < dis && (ascending ? arr[i] < arr[i + 1] : arr[i] > arr[i + 1])) i++;
if (ascending ? r >= arr[i] : r <= arr[i]) break;
arr[org] = arr[i];
org = i;
}
arr[org] = r;
}
}
4.3 插入排序
4.3.1 直接插入排序
package com.gyh.sort;
import java.util.Arrays;
public class DirectInsetSort implements Sort {
public static void main(String[] args) {
int[] nums = {2, 1, 17, 291, 92, 17, 817, 17};
new DirectInsetSort().sort(nums, false);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
int insetIndex;
int insertValue;
for (int i = 1; i < nums.length; i++) {
insetIndex = i - 1;
insertValue = nums[i];
while (insetIndex >= 0 && (ascending ? nums[insetIndex] > insertValue : nums[insetIndex] < insertValue)) {
nums[insetIndex + 1] = nums[insetIndex];
insetIndex--;
}
if (insetIndex + 1 != i) {
nums[insetIndex + 1] = insertValue;
}
}
}
}
4.3.2 折半插入排序(书上补充P238)
package com.gyh.sort;
import java.util.Arrays;
public class BinaryInsertSort implements Sort {
public static void main(String[] args) {
int[] nums = {2, 1, 17, 291, 92, 17, 817, 17};
new BinaryInsertSort().sort(nums, false);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
int low, high, mid;
int temp;
for (int i = 1; i < nums.length; i++) {
low = 0;
high = i - 1;
while (low <= high) {
mid = (low + high) / 2;
if (ascending ? nums[mid] > nums[i] : nums[mid] < nums[i]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
temp = nums[i];
for (int j = i - 1; j >= high + 1; j--) {
nums[j + 1] = nums[j];
}
nums[high + 1] = temp;
}
}
}
4.3.3 希尔排序
package com.gyh.sort;
import java.util.Arrays;
public class ShellSort implements Sort {
public static void main(String[] args) {
int[] nums = {2, 1, 17, 291, 92, 17, 817, 17, 3};
new ShellSort().sort(nums, false);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
int temp;
int count = 0;
for (int gap = nums.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < nums.length; i++) {
for (int j = i - gap; j >= 0; j -= gap) {
if (ascending ? nums[j] > nums[j + gap] : nums[j] < nums[j + gap]) {
temp = nums[j];
nums[j] = nums[j + gap];
nums[j + gap] = temp;
}
}
}
System.out.println("希尔排序第" + (++count) + "轮 =" + Arrays.toString(nums));
}
}
}
package com.gyh.sort;
import java.util.Arrays;
public class ShellSort2 implements Sort {
public static void main(String[] args) {
int[] nums = {2, 1, 17, 291, 92, 17, 817, 17};
new ShellSort2().sort(nums, false);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
int count = 0;
for (int gap = nums.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < nums.length; i++) {
int insetIndex = i - gap;
int insertValue = nums[i];
while (insetIndex >= 0 && (ascending ? nums[insetIndex] > insertValue : nums[insetIndex] < insertValue)) {
nums[insetIndex + gap] = nums[insetIndex];
insetIndex -= gap;
}
nums[insetIndex + gap] = insertValue;
}
System.out.println("希尔排序第" + (++count) + "轮 =" + Arrays.toString(nums));
}
}
}
五、归并排序
package com.gyh.sort;
import java.util.Arrays;
public class MergingSort implements Sort {
public static void main(String[] args) {
int[] nums = {8, 4, 5, 7, 1, 3, 6, 2,9};
new MergingSort().sort(nums, true);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
mergeSort(nums, 0, nums.length - 1, new int[nums.length], ascending);
}
private void mergeSort(int[] nums, int left, int right, int[] temp, boolean ascending) {
int mid;
if (left < right) {
mid = (left + right) / 2;
mergeSort(nums, left, mid, temp, ascending);
mergeSort(nums, mid + 1, right, temp, ascending);
merge(nums, left, mid, right, temp, ascending);
}
}
private void merge(int[] nums, int left, int mid, int right, int[] temp, boolean ascending) {
int l = left;
int r = mid + 1;
int cur = 0;
while (l <= mid && r <= right) {
if (ascending ? nums[l] <= nums[r] : nums[l] >= nums[r]) {
temp[cur++] = nums[l++];
} else {
temp[cur++] = nums[r++];
}
}
while (l <= mid) temp[cur++] = nums[l++];
while (r <= right) temp[cur++] = nums[r++];
int tempLeft = left;
cur = 0;
while (tempLeft <= right) {
nums[tempLeft++] = temp[cur++];
}
}
}
六、基数排序
package com.gyh.sort;
import java.util.ArrayList;
import java.util.Arrays;
public class RadixSorting implements Sort {
public static void main(String[] args) {
int[] nums = {2, 84, 17, 291, 92, 17, 817, 17};
new RadixSorting().sort(nums, false);
Arrays.stream(nums).forEach(System.out::println);
}
@Override
public void sort(int[] nums, boolean ascending) {
int max = nums[0];
for (int num : nums) {
if (num > max) {
max = num;
}
}
int maxLength = (max + "").length();
ArrayList<LinkedQueue<Integer>> bucket = new ArrayList<>();
for (int i = 0; i < 10; i++) {
bucket.add(new LinkedQueue<>());
}
int cur;
for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
for (int num : nums) {
int digitOfElement = num / n % 10;
bucket.get(digitOfElement).push(num);
}
cur = 0;
for (int j = 0; j < bucket.size(); j++) {
LinkedQueue<Integer> integerLinkedQueue = bucket.get(ascending ? j : bucket.size() - j - 1);
while (integerLinkedQueue.size() > 0) {
nums[cur++] = integerLinkedQueue.pop();
}
}
}
}
}
class LinkedQueue<T> {
private final Node<T> head;
private Node<T> rear;
private int size = 0;
public int size() {
return size;
}
public LinkedQueue() {
rear = new Node<>(null, null);
head = rear;
}
public boolean isEmpty() {
return head.next == null;
}
public void push(T d) {
rear.next = new Node<>(d, rear.next);
rear = rear.next;
size++;
}
public T pop() {
if (isEmpty()) {
throw new RuntimeException("没有元素");
}
T d = head.next.data;
if (rear == head.next) {
rear = head;
}
head.next = head.next.next;
size--;
return d;
}
}
class Node<T> {
T data;
Node<T> next;
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
}
七、排序算法总结