算法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 }
View Code

理解了荷兰国旗问题之后我们就可以使用荷兰国旗的思想来实现快速排序:

经典快排:

技术分享图片
 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 }
View Code

经典快速排序每次递归只能解决一个数,我们可以对做一下改进,每次递归的时候返回一个数组区间,该区间内的数的大小等于被比较的数

改进后的快速排序:

技术分享图片
 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 }
View Code

上面两种快速排序由于被比较的数每次都是最后一个,所以以上两种快速排序和数据状况有关系,所以我们可以采用随机数的方式每次随机选择被比较的数

随机快速排序:

技术分享图片
 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 }
View Code

根据期望值,这种随机快速排序的时间复杂度是 log(n)*n ,额外空间复杂度是 log(n).

 

以上是关于算法02的主要内容,如果未能解决你的问题,请参考以下文章

有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]

片段(Java) | 机试题+算法思路+考点+代码解析 2023

[linux][c/c++]代码片段02

vscode代码片段建议bug

java代码在片段活动中不起作用

Codeigniter 助手重复 HTML 代码片段