单向扫描
//单向的 void qsort1(int *arr, int begin, int end) { if(begin >= end) return ; int m = begin; //Assert arr[begin+1....m] < arr[begin] && arr[m+1....i-1] >=arr[begin] ) for(int i=begin+1; i<=end; i++) { if(arr[i] < arr[begin]) { //Swap(arr, ++m, i); m++; int tmp = arr[m]; arr[m] = arr[i]; arr[i] = tmp; } } //Assert arr[m] < arr[begin] && arr[m+1....end] >= arr[begin] //swap(arr, begin, m); int tmp = arr[begin]; arr[begin] = arr[m]; arr[m] = tmp; qsort1(arr, begin, m-1); qsort1(arr, m+1, end); }
单向扫描的劣势:针对数组所有元素相同情况下,交换次数太多,时间复杂度太高O(n^2)
双向扫描,在数组所有元素相同情况下,交换次数比qsort1少
//双向划分的快排 void qsort2(int *arr, int begin, int end) { if(begin >= end) return ; int b = begin; int e = end; int key = arr[begin]; //arr[begin] as a key while(b < e) { while(b < end && arr[b] <= key) b++; while(e > begin && arr[e] >= key) e--; if(b < e) { int tmp = arr[b]; arr[b] = arr[e]; arr[e] = tmp; } } arr[begin] = arr[e]; arr[e] = key; qsort2(arr, begin, e - 1); qsort2(arr, e + 1, end); }
第二种做法,类似上面代码
但是感觉应该比较次数能减少一些
//双向划分的快排 void qsort2(int *arr, int begin, int end) { if(begin >= end) return ; int b = begin; int e = end + 1; int key = arr[begin]; //arr[begin] as a key while(b < e) { while(b++ < e&& arr[b] <= key) ; while(e-- > b && arr[e] >= key) ; if(b < e) { int tmp = arr[b]; arr[b] = arr[e]; arr[e] = tmp; } } arr[begin] = arr[e]; arr[e] = key; qsort2(arr, begin, e - 1); qsort2(arr, e + 1, end); }
自动生成测试用例测试上述快排是否正确
随机打乱数组中的数
然后快排后,判断其是否有序
bool isSort(int *arr, int len) { if(len <= 1) return true; int i = 0; while(i < len - 1) { if(arr[i] > arr[i+1]) return false; else i++; } return true; } int main() { int arr[100]; //Test for(int j=0; j<100; j++) { //init for(int i=0; i<100; i++) arr[i] = i; //打乱数组中元素 for(int i=0; i<99; i++) { int index = rand()%(100-i) + i; int tmp = arr[index]; arr[index] = arr[i]; arr[i] = tmp; } qsort2(arr, 0, 99); if(isSort(arr, 100)) ; else printf("False/n"); } printf("END/n"); system("pause"); return 0; }