算法设计 java_算法设计:两种快速排序代码实现

快速排序是一种高效且使用广泛的排序算法,在很多语言的标准库中自带的排序都是快速排序,所以我们也有必要了解快排的原理以及其实现方法。

快排的大致思想

快速排序实现的重点在于数组的拆分,通常我们将数组的第一个元素定义为比较元素,然后将数组中小于比较元素的数放到左边,将大于比较元素的放到右边,

这样我们就将数组拆分成了左右两部分:小于比较元素的数组;大于比较元素的数组。我们再对这两个数组进行同样的拆分,直到拆分到不能再拆分,数组就自然而然地以升序排列了。

85565026176666d99d8adcc5163f11c4.png

不难看出,拆分算法是整个快速排序中的核心,快速排序拥有非常多的拆分方式,在本篇文章中我们介绍其中的两种,我个人将它称作:单指针遍历法与双指针遍历法(在下文中用英文单词split和partition称呼)

split算法解析

split算法使用一个单向的指针来对数组进行遍历,首先将数组首元素设置为比较元素,然后将第二个开始的元素依次与比较元素比较,如果大于比较元素则跳过,如果小于比较元素,则将其与前面较大的元素进行交换,将数组中所有元素交换完毕后,再将比较元素放到中间位置。

716e324f57ea2d0d48d2efed39d67564.png

split算法实现(c):

1 //划分数组的函数

2 int split(int a[], int low, inthigh)3 {4 int i = low; //i指向比较元素的期望位置

5 int x = a[i]; //将该数组第一个元素设置为比较元素6 //从数组的第二个元素起开始遍历,若找到的元素大于比较元素,则跳过

7 for(int j = low+1;j<=high;j++)8 //若找到了小于比较元素的数,则将其与前面较大的数进行交换

9 if (a[j] <=x)10 {11 i++;12 swap(a[i], a[j]);13 }14 swap(a[low], a[i]); //将比较元素交换到期望位置

15 returni;16 }

split算法实现(java):

1 //划分数组

2 public static int split(int a[], int low, inthigh)3 {4 int i = low; //i指向比较元素的期望位置

5 int x = a[low]; //将该组的第一个元素作为比较元素6 //从第二个元素开始,若当前元素大于比较元素,将其跳过

7 for(int j = low+1; j <= high; j++)8 //若找到了小于比较元素的元素,将其与前面较大的元素进行交换

9 if(a[j] <=x)10 {11 i++;12 if(i !=j)13 swap(a, i, j);14

15 }16 swap(a, i, low); //将比较元素交换到正确的位置上

17 return i; //返回比较元素的位置

18 }

partition算法解析

partition算法使用头尾两个方向相反的指针进行遍历,先将数组第一个元素设置为比较元素,头指针从左至右找到第一个大于比较元素的数,尾指针从右至左找到第一个小于比较元素的数,全部交换完毕后将比较元素放到中间位置。

34b22ceb6efd4aa2568f0c717317f4e5.png

partition算法实现(c):

1 int partition(int a[], int low, inthigh)2 {3 int x = a[low]; //将该数组第一个元素设置为比较元素

4 int i = low; //指向数组头的指针

5 int j = high; //指向数组尾的指针

6 while (i =x)9 j--; //从右至左找到第一个小于比较元素的数

10 while (i < j && a[i] <=x)11 i++; //从左至右找到第一个大于比较元素的数

12 /*需要注意的是,这里的j--与i++的顺序不可以调换!13 如果调换了顺序,i会走过头,以至于将后面较大的元素交换到数组开头*/

14

15 //将大数与小数交换

16 if (i !=j)17 swap(a[i], a[j]);18 }19 swap(a[low], a[i]); //将比较元素交换到期望位置

20 return i; //返回比较元素的位置

21 }

partition算法实现(java):

1 //划分数组

2 public static int partition(int a[], int low, inthigh)3 {4 int x = a[low]; //将该数组第一个元素设置为比较元素

5 int i=low;6 int j=high;7 while(i =x)12 j--;13

14

15 if(i!=j)16 swap(a, i, j);17 }18 swap(a, j, low);19 returnj;20 }

两种算法的完整代码和实际演示

split算法(c):

1 #include

2

3 void swap(int &a, int &b)4 {5 int t =a;6 a =b;7 b =t;8 }9

10 //划分数组的函数

11 int split(int a[], int low, inthigh)12 {13 int i = low; //i指向比较元素的期望位置

14 int x = a[i]; //将该数组第一个元素设置为比较元素15 //从数组的第二个元素起开始遍历,若找到的元素大于比较元素,则跳过

16 for(int j = low+1;j<=high;j++)17 //若找到了小于比较元素的数,则将其与前面较大的数进行交换

18 if (a[j] <=x)19 {20 i++;21 swap(a[i], a[j]);22 }23 swap(a[low], a[i]); //将比较元素交换到期望位置

24 returni;25 }26

27 //快速排序

28 void quicksort(int a[], int low, inthigh)29 {30 if (low

33 quicksort(a, low, i - 1); //对比较元素左边进行排序

34 quicksort(a, i + 1, high); //对比较元素右边进行排序

35 }36 }37

38 intmain()39 {40 int a[] = { 5,7,1,6,4,8,3,2};41 int length = sizeof(a) / sizeof(a[0]);42 quicksort(a, 0, length - 1);43 for (int i = 0; i < length; i++)44 printf("%d", a[i]);45 printf("\n");46 return 0;47 }

ba38bd919f5bf0f44bbe77c46bafe7a9.png

split算法(java):

1 //快速排序split实现方法

2 public classT1 {3 public static voidmain(String args[])4 {5 int a[] = {5,7,1,6,4,8,3,2};6 quickSort(a, 0, a.length-1);7 for(int i=0;i

12 //交换方法

13 public static void swap(int a[], int i, intj)14 {15 int t =a[i];16 a[i] =a[j];17 a[j] =t;18 }19

20 //划分数组

21 public static int split(int a[], int low, inthigh)22 {23 int i = low; //i指向比较元素的期望位置

24 int x = a[low]; //将该组的第一个元素作为比较元素25 //从第二个元素开始,若当前元素大于比较元素,将其跳过

26 for(int j = low+1; j <= high; j++)27 //若找到了小于比较元素的元素,将其与前面较大的元素进行交换

28 if(a[j] <=x)29 {30 i++;31 if(i !=j)32 swap(a, i, j);33

34 }35 swap(a, i, low); //将比较元素交换到正确的位置上

36 return i; //返回比较元素的位置

37 }38

39 public static void quickSort(int a[], int low, inthigh)40 {41 if(low

44 quickSort(a, low, i-1); //对比较元素左边的数组进行排序

45 quickSort(a, i+1, high); //对比较元素右边的数字进行排序

46 }47 }48 }

f26cfdd1b150b9ac027f95894dd599fa.png

partition算法(c):

1 #include

2

3 //交换函数

4 void swap(int &a, int &b)5 {6 int t =a;7 a =b;8 b =t;9 }10

11 int partition(int a[], int low, inthigh)12 {13 int x = a[low]; //将该数组第一个元素设置为比较元素

14 int i = low; //指向数组头的指针

15 int j = high; //指向数组尾的指针

16 while (i =x)19 j--; //从右至左找到第一个小于比较元素的数

20 while (i < j && a[i] <=x)21 i++; //从左至右找到第一个大于比较元素的数

22 /*需要注意的是,这里的j--与i++的顺序不可以调换!23 如果调换了顺序,i会走过头,以至于将后面较大的元素交换到数组开头*/

24

25 //将大数与小数交换

26 if (i !=j)27 swap(a[i], a[j]);28 }29 swap(a[low], a[i]); //将比较元素交换到期望位置

30 return i; //返回比较元素的位置

31 }32

33 void quicksort(int a[], int low, inthigh)34 {35 if (low

38 quicksort(a, low, i - 1); //对比较元素左边进行排序

39 quicksort(a, i + 1, high); //对比较元素右边进行排序

40 }41 }42

43 intmain()44 {45 int a[] = { 5,7,1,6,4,8,3,2};46 int length = sizeof(a) / sizeof(a[0]);47 quicksort(a, 0, length - 1);48 for (int i = 0; i < length; i++)49 printf("%d", a[i]);50 printf("\n");51 return 0;52 }

08645aa400cbabef797c6722afc1af15.png

partition算法(java):

1 //快速排序partition实现方法

2 public classT2 {3 public static voidmain(String args[])4 {5 int a[] = {5,7,1,6,4,8,3,2};6 quicksort(a, 0, a.length-1);7 for(int i=0;i

12 public static void swap(int a[], int i, intj)13 {14 int t =a[i];15 a[i] =a[j];16 a[j] =t;17 }18

19 //划分数组

20 public static int partition(int a[], int low, inthigh)21 {22 int x = a[low]; //将该数组第一个元素设置为比较元素

23 int i=low;24 int j=high;25 while(i =x)28 j--; //从右至左找到第一个小于比较元素的数

29 while(i

31 /*需要注意的是,这里的j--与i++的顺序不可以调换!32 *如果调换了顺序,i会走过头,以至于将后面较大的元素交换到数组开头*/

33

34 //将大数与小数交换

35 if(i!=j)36 swap(a, i, j);37 }38 swap(a, i, low); //将比较元素交换到期望位置

39 return i; //返回比较元素的位置

40 }41

42 public static void quicksort(int a[], int low, inthigh)43 {44 if(low

47 quicksort(a, low, i-1); //对比较元素左边进行排序

48 quicksort(a, i+1, high); //对比较元素右边进行排序

49 }50 }51 }

31c2f4b517c7635d1153d4dd311102fd.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值