快速排序是一种时间复杂度不太稳定的排序算法,是一种分治思想的排序算法。
这篇就谈一下随机化版本的快速排序的问题,所以快排就给个代码,表示学过了:
/** * 快速排序(QuickSort) */ #include <stdio.h> static int SortByParts(int* nums, int prev, int rear) { int i, j; int temp; int x = nums[rear]; j = prev - 1; for(i = prev; i < rear; i++) { if(nums[i] < x) { temp = nums[i]; nums[i] = nums[++j]; nums[j] = temp; } } temp = nums[rear]; nums[rear] = nums[j + 1]; nums[j + 1] = temp; return j + 1; } void QuickSort(int* nums, int prev, int rear) { int n; if(prev < rear) { n = SortByParts(nums, prev, rear); QuickSort(nums, prev, n - 1); QuickSort(nums, n + 1, rear); } } int main() { int arr[] = {2,8,7,1,3,5,6,4}, *nums = arr; int i; QuickSort(nums, 0, sizeof(arr)/sizeof(int) - 1); for(i = 0; i < sizeof(arr)/sizeof(int); i++) printf("%d ", arr[i]); printf(" "); return 0; }
随机化版本的快速排序,我比较迷惑的是产生随机数代码的地方,先看看代码(注释的部分):
#include <cstdio> #include <cstdlib> #include <ctime> static int Random(); static int RandomizedControl(); static int ArrayByParts(); void QuickSort(); static int Random(int prev, int rear) { return prev + rand()%(rear + 1 - prev); // 为什么不能是 rand()%(rear + 1 - prev) or rand()%(rear + 1)? } static int RandomizedControl(int* nums, int prev, int rear) { int i = Random(prev, rear); int temp; temp = nums[i]; nums[i] = nums[rear]; nums[rear] = temp; return ArrayByParts(nums, prev, rear); } static int ArrayByParts(int* nums, int prev, int rear) { int x = nums[rear]; int temp; int i, j; j = prev - 1; for(i = prev; i < rear; i++) { if(nums[i] < x) { temp = nums[i]; nums[i] = nums[++j]; nums[j] = temp; } } temp = nums[rear]; nums[rear] = nums[j + 1]; nums[j + 1] = temp; return j + 1; } void QuickSort(int * nums, int start, int end) { int mid; if(start < end) { mid = RandomizedControl(nums, start, end); QuickSort(nums, start, mid - 1); QuickSort(nums, mid + 1, end); } } int main(void) { int arr[] = {13,-3,-25,20,-16,-23,18,-7,12,-5,-22,15,-4,7}, * nums = arr; int i; srand(time(NULL)); QuickSort(nums, 0, sizeof(arr)/sizeof(int) - 1); for(i = 0; i < sizeof(arr)/sizeof(int); i++) printf("%d ", arr[i]); printf(" "); return 0; }
简版:
#include<bits/stdc++.h> using namespace std; #define ll long long const int N = 100010; void quicksort(int num[], int s, int e) { if (s < e) { srand(time(NULL)); int t = s + rand()%(e + 1 - s); swap(num[t], num[e]); int j = s - 1, x = num[e]; for (int i = s; i < e; i++) if (num[i] < x) swap(num[i], num[++j]); swap(num[j + 1], num[e]); quicksort(num, s, j); quicksort(num, j + 2, e); } } int main() { int num[N], n; cin >> n; for (int i = 0; i < n; i++) cin >> num[i]; quicksort(num, 0, n - 1); for (int i = 0; i < n; i++) cout << num[i] << ' '; return 0; }
尾递归版:
#include<bits/stdc++.h> using namespace std; #define ll long long const int N = 100010; void quicksort(int num[], int s, int e) { while (s < e) { srand(time(NULL)); int t = s + rand()%(e + 1 - s); swap(num[t], num[e]); int j = s - 1, x = num[e]; for (int i = s; i < e; i++) if (num[i] < x) swap(num[i], num[++j]); swap(num[j + 1], num[e]); quicksort(num, s, j); s = j + 1; } } int main() { int num[N], n; cin >> n; for (int i = 0; i < n; i++) cin >> num[i]; quicksort(num, 0, n - 1); for (int i = 0; i < n; i++) cout << num[i] << ' '; return 0; }