快速排序——一次快排的应用(笔试&面试)

将数组中的大写字母与小写字母分开

:一个数组总存储有且in有大写和小写字母,编写一个函数对数组内的字母重新排列,让小写字母在所有大写字母之前。(相对顺序没有要求)【2012·中兴、2013·腾讯】

使用快排的一次排列即可实现,代码如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 using namespace std;
 5
 6 bool isUpper( char ch ) //equal isupper()
 7 {
 8     if( ch >=‘A‘ && ch <= ‘Z‘)
 9         return true;
10     return false;
11 }
12
13 bool isLower( char ch )//equal islower()
14 {
15     if( ch >= ‘a‘ && ch <= ‘z‘)
16         return true;
17     return false;
18 }
19
20 void Partition(string &arr, int len) //快排的一次排序过程
21 {
22     if( len <= 1)
23         return;
24
25     int low = 0;
26     int high = len-1;
27
28     while( low < high)
29     {
30         while( low < high && isUpper(arr[high]) ) --high; //如果是大写字母,位置向前移动
31         while( low < high && isLower(arr[low]) ) ++low; //如果是小写字母,位置向后移动
32         char tmp = arr[low]; //交换
33         arr[low] = arr[high];
34         arr[high] = tmp;
35     }
36 }
37
38 int main(int argc, char const *argv[])
39 {
40     string  str= "HElloWorlDThanKYOU";
41     cout <<"Before: "<< str << endl;;
42
43     Partition( str, str.size() );
44     cout <<"After : "<< str << endl;
45     return 0;
46 }

:给定含有 n 个元素的整形数组 arr, 其中包括 0 元素和非 0 元素,对数组进行排列,要求:【2012·人民搜索】
1、排序后所有 0 元素在前,所有非零元素在后,且非零元素排序前后相对位置不变。

2、不能使用额外存储空间;

例如:

输入 0、 3 、0、 2、1、 0、 0

输出 0、 0、 0、 0、 3、 2、1

思路:此处要求非零元素排序前后相对位置不变,因此可以利用快苏排序一次排序的第二种情况(两个指针索引一前一后移动),代码如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 using namespace std;
 5
 6 const int N = 7;
 7 void ZeroPatition( int *arr, int len)
 8 {
 9     int slow =len-1; //最末尾一个元素
10
11     for(int fast = slow; fast>=0; --fast)
12     {
13         if( arr[fast] != 0)
14         {
15             if( slow != fast) //位置不同时交换
16             {
17                 arr[slow] = arr[fast];
18                 arr[fast] =0;
19             }
20             slow--;//向前移动
21         }
22     }
23 }
24
25 void print(int *arr, int len)
26 {
27     for(int i= 0; i < len; ++i)
28         cout << arr[i]<<" ";
29     cout << endl;
30 }
31
32 int main(int argc, char const *argv[])
33 {
34     //int arr[N] = {0, 3, 0, 2, 1, 0, 0};
35     int arr[N] = {0, 3, 0, 0, 2, 0, 1};
36     print(arr, N);
37
38     ZeroPatition(arr, N);
39     print(arr, N);
40     return 0;
41 }

三:荷兰国旗问题

将乱序的红白蓝三色小球排列成同颜色在一起的小球组(按照红白蓝排序),这个问题称为荷兰国旗问题。

这是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗。如下图所示:其中 0代表红球,2为篮球,1为白球。

解答:这个问题类似于快排中的partition过程。不过,要用三个指针,一前begin、一中current、一后end。begin与current同时初始化为数组首部,end初始化指向数组尾部

1、current遍历整个数组序列,current指1时,不交换,current++;
2、current指0时,与begin交换,而后current++,begin++;
3、current指2时,与end交换,而后current不动,end--。

主体代码如下:

 1 //荷兰国旗问题
 2 void Flag_Netherland(int *arr, int len)
 3 {
 4     int current =0, begin =0, end = len-1;
 5
 6     while(current <= end)
 7     {
 8         if(arr[current] == 0)
 9         {
10             swap(&arr[begin], &arr[current]);
11             current ++;
12             begin++;
13         }
14         else if( arr[current] == 1)
15         {
16             current ++;
17         }
18         else // arr[current]==2
19         {
20             swap( &arr[current], &arr[end]);
21             end--;
22         }
23     }
24 }

完整代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <time.h>
 5 #define N 10
 6
 7 void print_Arr(int *arr, int len)
 8 {
 9     int i;
10     for (i = 0; i < len; ++i)
11     {
12         printf("%2d", arr[i]);
13     }
14     printf("\n");
15 }
16
17 void init_Arr(int *arr, int len)
18 {
19     int i = 0;
20     while( i < len)
21     {
22         arr[i] = rand()%3;
23         ++i;
24     }
25 }
26
27 void swap(int* left, int *right)
28 {
29     int tmp = *left;
30     *left = *right;
31     *right = tmp;
32 }
33
34 //荷兰国旗问题
35 void Flag_Netherland(int *arr, int len)
36 {
37     int current =0, begin =0, end = len-1;
38
39     while(current <= end)
40     {
41         if(arr[current] == 0)
42         {
43             swap(&arr[begin], &arr[current]);
44             current ++;
45             begin++;
46         }
47         else if( arr[current] == 1)
48         {
49             current ++;
50         }
51         else // arr[current]==2
52         {
53             swap( &arr[current], &arr[end]);
54             end--;
55         }
56     }
57 }
58
59 int main(int argc, char const *argv[])
60 {
61     srand(time(NULL));
62
63     int arr[N];
64     init_Arr(arr, N);
65     printf("Before:\n");
66     print_Arr(arr, N);
67
68     Flag_Netherland(arr, N);
69     printf("After\n");
70     print_Arr(arr, N);
71     return 0;
72 }

完毕。

时间: 2024-10-10 22:45:54

快速排序——一次快排的应用(笔试&面试)的相关文章

快速排序(经典快排以及随机快排)

快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 首先来了解一下经典快排: 其中就小于等于的区域可以优化一下,小于的放小于区域,等于的放等于区域,大于的放大于区域.可以利用荷兰国旗问题 荷兰国旗问题: 给定一个数组arr

Python实现排序(冒泡、快排、归并)

Thomas H.Cormen 的<算法导论>上介绍的几个经典排序算法的Python实现. 1.冒泡排序: 简单的两重循环遍历,使最小(最大)的值不断地往上升(下沉)而实现的排序,算法时间为O(n2). 代码如下: 1 def up_sort(a): 2 # 冒泡排序 3 4 a_length = len(a) 5 while True: 6 i = 0 7 j = 1 8 9 while True: 10 if a[i] > a[j]: 11 a[i], a[j] = a[j], a[

排序之快排

排序是将一串数据按照其某个或者某些关键字的大小进行递增或递减排列的操作我,通常指的排序是升序,排序方式是原地排序 下面介绍下快速排序,简称快排 快排 原理: 从待排序区间选择一个数,作为基准值(pivot) Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可以包含相等的)放到基准值的右边 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度等于1,代表已经有序,或者小区间的长度等于0,代表没有数据. 快排是一个不稳定的排序

快速排序—三路快排 vs 双基准

快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Java 7发布两年后)快速排序实现的Arrays.sort被双基准(dual-pivot)排序的一种变体取代了.这篇文章不仅展示了为什么这个变化如此优秀,而且让我们看到Jon Bentley和Joshua Bloch的谦逊. 我当时做了什么? 与所有人一样,我想实现这个算法并且对一千万个数值排序(随机

快排---快速排序

//快速排序 void quick_sort(int s[], int l, int r) { if (l < r) { //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1 int i = l, j = r, x = s[l]; while (i < j) { while(i < j && s[j] >= x) // 从右向左找第一个小于x的数 j--; if(i < j) s[i++] = s[j]; wh

快速排序(快排)

快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 算法处理过程(截图参考 坐在马桶上看算法:快速排序): 代码: public class QuickSort { public static void sort(int[] arr, int low, int high){ i

快速排序--QuickSort,看完五分彩开奖网平台搭建自己就能写出来的快排思路推演

快速五分彩开奖网平台搭建论坛:haozbbs.com Q1446595067排序(QuickSort)介绍首先发明者竟然敢给自己发明的算法叫做QuickSort,这个名字闪不闪亮?好比别的武功叫做六脉神剑.降龙十八掌,我这个叫做"天下无敌神功".别的排序算法都是按照特点来起的,你这个不是应该叫分块递归排序法吗?或者和希尔一样,叫做霍尔排序也可以啊,这么高调是要干啥啊?我给了他一次机会,特意去查了一下,这个名字并不是江湖朋友抬爱给的,就是发明者自己起的,社会社会...不过看完这篇博客,理

快排 快速排序 qsort quicksort C语言

现在网上搜到的快排和我以前打的不太一样,感觉有点复杂,我用的快排是FreePascal里/demo/text/qsort.pp的风格,感觉特别简洁. 1 #include<stdio.h> 2 #define MAXN 10000 3 int a[MAXN]; 4 int n; 5 void Mysort(int l, int r) { 6 int x,y,mid,t; 7 mid = a[(l+r)/2]; 8 x=l; 9 y=r; 10 do { 11 while(a[x]<mid

常见经典排序算法学习总结,附算法原理及实现代码(插入、shell、冒泡、选择、归并、快排等)

博主在学习过程中深感基础的重要,经典排序算法是数据结构与算法学习过程中重要的一环,这里对笔试面试最常涉及到的7种排序算法(包括插入排序.希尔排序.选择排序.冒泡排序.快速排序.堆排序.归并排序)进行了详解.每一种算法都有基本介绍.算法原理分析.算法代码. 转载请注明出处:http://blog.csdn.net/lsh_2013/article/details/47280135 插入排序 1)算法简介 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过