感谢“啊哈磊”大神的神奇算法书~《啊哈!算法》
鼎力推荐
桶排序太消耗空间,冒泡排序太消耗时间,那怎么办呢?
于是有了快速排序:
大体思路:
从小到大排:
- 找一个基准数,一般是左边第一个(这里要注意,如果基准数是左边第一个,就要从右边先开始)
- 从右边开始一个一个找比基准数小的数停下,然后从左边开始一个一个找比基准数大的数停下,碰头即止;
- 如果两边都找到了,交换;
- 碰头了,则将碰头的数与基准数交换;
- 交换完成后,这时基准数已归位,将基准数左边和基准数右边分开,分别单独进行快速排序,使用递归思想;
- 当left>right时return。
C代码如下:
#include <stdio.h>
int a[101];//定义全局变量,这个变量需要在子函数中使用
/*快速排序算法*/
void quickSort(int left, int right) {
int i, j, t, temp;
if (left > right) {
return;
}
temp = a[left];//temp中存基准数
i = left;
j = right;
//当i!=j时
while (i != j) {
//顺序很重要,要先从右往左找;因为当i和j碰头时要和基准数互换,如果先从左边找,i和j碰头的数就会大于基准数,这样就不对了
while (a[j] >= temp&&i < j) {//一直找,直到找到一个比基准数小的数,或者i和j碰头
j--;
}
//再从左往右找
while (a[i] <= temp&&i < j) {
i++;
}
//如果i和j没碰头的话,交换他们的位置
if (i < j) {
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//将基准数交换
a[left] = a[i];//将i和j碰头的数与基准数交换
a[i] = temp;
//递归排序左边和右边
quickSort(left, i - 1);
quickSort(i + 1, right);
}
/*主函数*/
int main() {
int n;
scanf_s("%d", &n, 1);//输入排序的个数
//输入数据
for (int i = 0; i < n; i++) {
scanf_s("%d", &a[i], 1);
}
//快速排序
quickSort(0, n - 1);
for (int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
getchar();
getchar();
return 0;
}
Java代码:
package com.waka.workspace;
import java.util.Scanner;
public class Main {
private static int[] a = new int[100];
public static void main(String[] args) {
int n = -1;
Scanner in = new Scanner(System.in);
n = in.nextInt();//输入个数
//输入数据
for (int i = 0; i < n; i++) {
a[i] = in.nextInt();
}
//快速排序
quickSort(0, n - 1);
//输出结果
for (int i = 0; i < n; i++) {
System.out.print(a[i] + " ");
}
}
/**
* 快速排序
*/
private static void quickSort(int left, int right) {
int i, j, t, temp;//temp是基准数
if (left > right) {
return;
}
i = left;
j = right;
temp = a[left];
//当i!=j时一直循环
while (i != j) {
//先从右往左开始
while (a[j] >= temp && i < j) {
j--;
}
//再从左往右开始
while (a[i] <= temp && i < j) {
i++;
}
//如果i<j,交换他们
if (i < j) {
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//当i和j碰头时,将a[i]或a[j]与基准数交换
a[left] = a[i];
a[i] = temp;
//递归排序
quickSort(left, i - 1);
quickSort(i + 1, right);
}
}