快速排序-java

快速排序

快速排序是排序算法中较优秀的算法,下面将用的递归的形式来实现.
首先是需要的工具类.

工具类

random()功能:给数组赋予随机值.代码:

public static void random(int[] a) {
	for(int i = 0; i < a.length; i++) {
		a[i] = new Random().nextInt(100)+1;//给数组赋1~100(包括100)的值
	}
}

不要忘记导入java.util.Random包.


swap()功能:交换两个下标对应的数组值.代码:

public static void swap(int[] a, int m, int n){
	int temp = 0;
	temp = a[m];
	a[m] = a[n];
	a[n] = temp;
}

printf()功能:打印数组,方便更直观的观察数组.代码:

public static void printf(int[] a){
	System.out.print("{");
		for (int i = 0; i < a.length; i++) {
			if (i == a.length - 1)
				System.out.print(a[i]);
			else
				System.out.print(a[i] + " ");
		}
		System.out.println("}");
}

介绍完工具类,上题.

题目+分析:

题目:用快速排序将一个数组排序.

主元(指你从数组中选出来与其余数比较的一个数)

分析:快速排序的思想是先将比(主元)小的数放一边,比(主元)大的数放另一边.这就将数组一分为二.
然后再将"两份"数组分别再次进行比较就变成"四份"数组,这里可以思考为什么快速排序算法较为优秀.

如果每次运气好都选到处于中间位值的那个数(比这个数大的数与比这个数小的数的个数一样),那么
第一次排序下来可以排好一个数,
在这里插入图片描述
第二次就能排好两个+一个数,
在这里插入图片描述
第三次就是四个+两个+一个数,
在这里插入图片描述
第四次八个数.(图略)
相信大家肯定明白了.随着排序次数增多,每次能排好的数呈"指数爆炸"的形式增长.


了解了原理过后怎么去实现它呢,我们再看看实现的原理:
我们定义两个"指针",这里的指针不是C语言中指向地址的指针,而是数组的下标.
左指针:开始时为0,也就是指向a[0].
右指针:开始时为a.length-1,也就是指向数组的最后一个数.
在这里插入图片描述
这时,两个指针相向运动.
移动的条件:左指针指向的数比主元小就向右移动,遇到比主元大的数则停下.
右指针指向的数比主元大就向左移动,遇到比主元小的数则停下.
当两指针停下时,交换两指针所指的数,指针位置不变,交换后,继续移动,直到两指针相错.
在这里插入图片描述
两指针最后会相遇,相遇过后,如果left指的数比主元大,那么交换,left向右移动,right向左移动,即,最后两指针会相错.
在这里插入图片描述
终于到了最后一步,此时右指针所指的数的左边及自己都是比主元小的数,将右指针的位置与主元的位置交换 ,主元的排序位置就是正确的,接下来就递归重复这个过程就能完成排序.

实现代码:

public class QuickSort {
	public static void main(String[] args) {
		int a[] = new int[10];//这里以长度为10的数组做实验,根据具体需求可以改动
		random(a);//产生随机数组
		int p = new Random().nextInt(10);//产生随机主元,这里随机数范围需要跟数组长度一致
		printf(a);//打印排序前的数组
		quicksort(a, p, a.length-1);
		printf(a);//打印排序后的数组
	}

	public static void quicksort(int[] a, int p, int r) {// a[p]做主元
		if (p <= r) {
			int q = pivot(a, p, r);//对主元进行排序
			quicksort(a, 0, q-1);//对第一次排序后的左边部分再次进行排序
			quicksort(a, q+1, r);//对第一次排序后的右边部分再次进行排序
		}
	}

	public static int pivot(int[] a, int p, int r) {
		int left = 0;//左指针
		int right = r ;//右指针
		while (left <= right) {
			while (left <= right&&a[left] <= a[p])//这里的left<=right是防止指针越界,例如a[0]为最大的数,left就会指向a[a.length],而a.length并不存在.
				left++;
			while (right >= left&&a[right] > a[p])//right>=left同上,为防止指针越界
				right--;
			if (left < right)//最后,left与right相错时不用交换
				swap(a, left, right);
		}
		swap(a, p, right);//交换主元与右指针的数,主元排序完毕
		return right;
	}
感谢您看到此处,相信您也能从中学习到一些东西.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值