蓝桥杯-快速排序

快排属于分治算法,分治算法都有三步:

  • 分成子问题
  • 递归处理子问题
  • 子问题合并

题目描述
给定你一个长度为n的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

第一种:以j为边界;

import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int[] arr = new int[n];
		for(int i = 0 ;i < n ;i++) {
			arr[i] = scan.nextInt();
		}
		quick_sort(arr,0,n-1);
		for(int i = 0 ; i < n ;i++) {
			System.out.print(arr[i]+" ");
		}
	}
	
	public static void quick_sort(int[] arr,int l,int r) {
		if(l >= r) return;
		int x = arr[l+r>>1],i = l-1,j = r+1;
		while(i<j) {
			while(arr[++i]<x);
			while(arr[--j]>x);
			if(i<j) {
				int t = arr[i];
				arr[i] = arr[j];
				arr[j] = t;
			}
		}
		quick_sort(arr,l,j);
		quick_sort(arr,j+1,r);
	}	
}

 本算法采用递归的思想;首先先确定左右的边界,然后确定其分界点(此题取中间值),(用的是右移运算符,>>运算符比+的优先级低,所以会先进行加法运算,再进行右移运算符,功能等同于除2);采用i,j两个指针来进行移动,若在满足i<j的前提时,若x左边的值小于x,则右移一位,循环执行;如果大于或者等于下,则退出循环,当右边也出现小于或者等于x的情况下,两者进行交换。

边界值分析易错:

防止出现n分成0和n,或 n分成n和0的情况,否则会造成死循环,无限划分。

如第二种当使用i为边界时,假如有两个数(6,3)进行快速排序,下标是0-1;若此时中间值取q[L+R>>2],时,下标为0,即分界值为6,i对应的内容为6,与边界值相同,不进行右移操作;j对应的内容为3,其小于x,故也不进行左移,此时i<j,进行交换;紧接着执行quick_sort(arr,l,i - 1);l=0,i-1=0;再执行quick_sort(arr,i,r),i=0,r=1;(符合n分成0和n,或 n分成n和0的情况,否则会造成死循环,无限划分这种情况)这与刚开始的范围没有变化,即使往下进行递归,也依然是这样的结果,永远也达不到递归终止的条件,造成死循环。

结论:此题分界值选取的为中间值,若题目的数据量并没有那么大时,边界值也可以在最右或者最左等都可以(若以i为边界,则不能使边界值x=arr[l],以为边界时,则不能使边界值x=[r])。

第二种:以i为边界,(注意对中间值x进行赋值与第一种的不同)

package com.zy.Acwing;
import java.util.*;
/**
 * 快速排序模板
 * @author zhaoyan
 *
 */
public class P785 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int[] arr = new int[n];
		for(int i = 0 ;i < n ;i++) {
			arr[i] = scan.nextInt();
		}
		quick_sort(arr,0,n-1);
		for(int i = 0 ; i < n ;i++) {
			System.out.print(arr[i]+" ");
		}
	}
	
	public static void quick_sort(int[] arr,int l,int r) {
		if(l >= r) return;
		int x = arr[l+r+1>>1],i = l-1,j = r+1;
		while(i<j) {
			while(arr[++i]<x);
			while(arr[--j]>x);
			if(i<j) {
				int t = arr[i];
				arr[i] = arr[j];
				arr[j] = t;
			}
		}
		//quick_sort(arr,l,j);
		//quick_sort(arr,j+1,r);
		quick_sort(arr,l,i - 1);
		quick_sort(arr,i,r);
	}	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值