publicvoidshellSort(int[] arr) { intn= arr.length; for (intgap= n/2; gap > 0; gap /= 2) { for (inti= gap; i < n; i++) { intkey= arr[i]; intj= i; while (j >= gap && arr[j - gap] > key) { arr[j] = arr[j - gap]; j -= gap; } arr[j] = key; } } }
4.3 C++实现
1 2 3 4 5 6 7 8 9 10 11 12 13
voidshellSort(int arr[], int n){ for (int gap = n/2; gap > 0; gap /= 2) { for (int i = gap; i < n; i++) { int key = arr[i]; int j = i; while (j >= gap && arr[j - gap] > key) { arr[j] = arr[j - gap]; j -= gap; } arr[j] = key; } } }
4.4 复杂度分析
时间复杂度:O(n log n) ~ O(n^2)
空间复杂度:O(1)
稳定性:不稳定
5. 归并排序(Merge Sort)
5.1 算法原理
归并排序采用分治法(Divide and Conquer)策略。它将问题分成一些小的问题然后递归求解,而治的阶段则将分的阶段得到的各答案”修补”在一起。
intpartition(int arr[], int low, int high){ int pivot = arr[high]; int i = (low - 1); for (int j = low; j <= high - 1; j++) { if (arr[j] < pivot) { i++; int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } int temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return (i + 1); }
voidquickSort(int arr[], int low, int high){ if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } }
publicvoidheapSort(int[] arr) { intn= arr.length; for (inti= n / 2 - 1; i >= 0; i--) { heapify(arr, n, i); } for (inti= n - 1; i > 0; i--) { inttemp= arr[0]; arr[0] = arr[i]; arr[i] = temp; heapify(arr, i, 0); } } voidheapify(int[] arr, int n, int i) { intlargest= i; intl=2 * i + 1; intr=2 * i + 2; if (l < n && arr[l] > arr[largest]) largest = l; if (r < n && arr[r] > arr[largest]) largest = r; if (largest != i) { intswap= arr[i]; arr[i] = arr[largest]; arr[largest] = swap; heapify(arr, n, largest); } }
voidheapify(int arr[], int n, int i){ int largest = i; int l = 2*i + 1; int r = 2*i + 2; if (l < n && arr[l] > arr[largest]) largest = l; if (r < n && arr[r] > arr[largest]) largest = r; if (largest != i) { int temp = arr[i]; arr[i] = arr[largest]; arr[largest] = temp; heapify(arr, n, largest); } }
voidheapSort(int arr[], int n){ for (int i = n / 2 - 1; i >= 0; i--) { heapify(arr, n, i); } for (int i=n-1; i>0; i--) { int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; heapify(arr, i, 0); } }
voidcountSort(int arr[], int n){ int max = *max_element(arr, arr+n); int min = *min_element(arr, arr+n); int range = max - min + 1; vector<int> count(range), output(n); for (int i = 0; i < n; i++) { count[arr[i] - min]++; } for (int i = 1; i < count.size(); i++) { count[i] += count[i - 1]; } for (int i = n - 1; i >= 0; i--) { output[count[arr[i] - min] - 1] = arr[i]; count[arr[i] - min]--; } for (int i = 0; i < n; i++) { arr[i] = output[i]; } }
voidbucketSort(int arr[], int n){ int max_val = *max_element(arr, arr+n); int min_val = *min_element(arr, arr+n); int bucket_size = (max_val - min_val) / n + 1; vector<vector<int>> buckets(n); for (int i = 0; i < n; i++) { int bucket_index = (arr[i] - min_val) / bucket_size; buckets[bucket_index].push_back(arr[i]); } for (int i = 0; i < n; i++) { sort(buckets[i].begin(), buckets[i].end()); } int index = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < buckets[i].size(); j++) { arr[index++] = buckets[i][j]; } } }
intgetMax(int arr[], int n){ int mx = arr[0]; for (int i = 1; i < n; i++) { if (arr[i] > mx) mx = arr[i]; } return mx; } voidcountSort(int arr[], int n, int exp){ int output[n]; int i, count[10] = {0}; for (i = 0; i < n; i++) { count[(arr[i] / exp) % 10]++; } for (i = 1; i < 10; i++) { count[i] += count[i - 1]; } for (i = n - 1; i >= 0; i--) { output[count[(arr[i] / exp) % 10] - 1] = arr[i]; count[(arr[i] / exp) % 10]--; } for (i = 0; i < n; i++) { arr[i] = output[i]; } } voidradixSort(int arr[], int n){ int m = getMax(arr, n); for (int exp = 1; m/exp > 0; exp *= 10) { countSort(arr, n, exp); } }