算法02
Posted luojianyi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法02相关的知识,希望对你有一定的参考价值。
荷兰国旗问题,给定一个数组,将小于num的数放在左边,等于num的数放在中间,大于num的数放在右边
code:
1 void hlflags(int *l, int num, int size)//第一个参数是一个数组,第二个参数是比较值num,第三个参数是数组的长度 2 { 3 int p1 = -1, p2 = size; //下标小于等于p1都是小于num的数字,p2相反 4 int index = 0; 5 for (int i = 0; i < 10; i++) 6 { 7 cout << l[i] << " "; 8 } 9 cout << endl; 10 while (index != p2) 11 { 12 if (l[index] == num) 13 { 14 index++; 15 } 16 else if (l[index] < num) 17 { 18 int item = l[index]; 19 l[index] = l[++p1]; 20 l[p1] = item; 21 index++; //小于的时候这个下标也要加1 22 } 23 else 24 { 25 int item = l[index]; 26 l[index] = l[--p2]; 27 l[p2] = item; 28 } 29 cout << "index:" << index << " p1:" << p1 << " p2:" << p2 << endl; 30 } 31 }
理解了荷兰国旗问题之后我们就可以使用荷兰国旗的思想来实现快速排序:
经典快排:
1 void quicksort(int *arr, int l, int r)//第一个参数是数组,第二个参数是左边界,第三个参数是右边界 2 { 3 if (l < r) 4 { 5 int a = partition(arr, l, r); 6 quicksort(arr, l, a - 1); 7 quicksort(arr, a + 1, r); 8 } 9 } 10 11 int partition(int *arr, int l, int r) 12 { 13 int less = l - 1; 14 int more = r; 15 while(l < more) 16 { 17 if (arr[l] < arr[r]) 18 { 19 swap(arr[l++], arr[++less]); 20 } 21 else if (arr[l] > arr[r]) 22 { 23 swap(arr[l], arr[--more]); 24 } 25 else 26 { 27 l++; 28 } 29 } 30 swap(arr[r], arr[more]); 31 return more; 32 }
经典快速排序每次递归只能解决一个数,我们可以对做一下改进,每次递归的时候返回一个数组区间,该区间内的数的大小等于被比较的数
改进后的快速排序:
1 void quicksort(int *arr, int l, int r) 2 { 3 if (l < r) 4 { 5 int *a = partition(arr, l, r); 6 quicksort(arr, l, a[0]); 7 quicksort(arr, a[1]+1, r); 8 delete[] a; 9 } 10 } 11 12 int* partition(int *arr, int l, int r) 13 { 14 int less = l - 1; 15 int more = r; 16 while(l < more) 17 { 18 if (arr[l] < arr[r]) 19 { 20 swap(arr[l++], arr[++less]); 21 } 22 else if (arr[l] > arr[r]) 23 { 24 swap(arr[l], arr[--more]); 25 } 26 else 27 { 28 l++; 29 } 30 } 31 swap(arr[r], arr[more]); 32 int *a = new int[2]; 33 a[0] = less; 34 a[1] = more; 35 return a; 36 }
上面两种快速排序由于被比较的数每次都是最后一个,所以以上两种快速排序和数据状况有关系,所以我们可以采用随机数的方式每次随机选择被比较的数
随机快速排序:
1 void quicksort(int *arr, int l, int r) 2 { 3 if (l < r) 4 { 5 int *a = partition(arr, l, r); 6 quicksort(arr, l, a[0]); 7 quicksort(arr, a[1]+1, r); 8 delete[] a; 9 } 10 } 11 12 int* partition(int *arr, int l, int r) 13 { 14 int less = l - 1; 15 int more = r; 16 17 srand(time(NULL)); 18 int t = int(rand()) % (r - l + 1) + l; 19 swap(arr[t], arr[r]); 20 //这三行代码就实现了随机快速排序 21 while(l < more) 22 { 23 if (arr[l] < arr[r]) 24 { 25 swap(arr[l++], arr[++less]); 26 } 27 else if (arr[l] > arr[r]) 28 { 29 swap(arr[l], arr[--more]); 30 } 31 else 32 { 33 l++; 34 } 35 } 36 swap(arr[r], arr[more]); 37 int *a = new int[2]; 38 a[0] = less; 39 a[1] = more; 40 return a; 41 }
根据期望值,这种随机快速排序的时间复杂度是 log(n)*n ,额外空间复杂度是 log(n).
以上是关于算法02的主要内容,如果未能解决你的问题,请参考以下文章
有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]