快速排序算法

温习以前学过的东西时,突然发现不记得快速排序的内容是什么了。

于是决定重写一遍。网上写这种算法的文章挺多的,呵呵。

快速排序的思想是选其中一个数为基准值,然后拿数组中的其它数和基准数比较,比它小的放在前面,比它大的放在后面,然后分别对比它小的那组数据进行排序、对比它大的那组数据进行排序……

我的想法是取一个基准数,然后拿后面所有的数跟它比较,找出所有比它小的数,然后把基准数置换到中间,后面必然都是比它大的数,这样也达到了分组的目的。

具体如下:以第一个数为基准数,遍历数组,找到第一个比基准数小的数,就把那个数置换到数组的第一位上,如果找打第二位比基准数小,就把这个数放到数组的第二位上……同时记录基准数的位置,找完所有小的数以后再把基准数置换到中间,数组后面的部分必然都是比基准数大的数了,然后进行分组迭代排序……

import java.util.Arrays;

/**
 * 快速排序
 *
 */
public class QuickSort 
{
	
	public static void sort(int[] arr)
	{
		sort(arr,0,arr.length-1);
	}
	
	/**
	 * 快速排序
	 * 
	 * @param arr
	 * @param low
	 * @param high
	 */
	private static void sort(int[] arr,int low,int high)
	{
		if(low<high)
		{
			int baseIndex = group(arr,low,high);

			sort(arr,low,baseIndex-1);
			
			sort(arr,baseIndex+1,high);
		}
	}
	
	/**
	 * 一轮排序:选定基准值,和数组中得所有元素依次进行比较,
	 * 凡是比基准值小的都置换到数组的最前面(从第一个依次往后排),
	 * 并记录当前的基准值位置,最后把基准值置换到分界位置
	 * @param arr 数组
	 * @param low 当前分组中最低位的索引号
	 * @param high 当前分组中最高位的索引号
	 * @return 基准值的位置
	 */
	private static int group(int[] arr,int low,int high)
	{
		//选定基准值
		int base = arr[low];
		//记录基准值的位置
		int baseIndex = low;
		//记录一轮比较中交换不成功的次数
		int loseCount = 0;
		
		while(loseCount<=(high-low))
		{
			//记录不比基准值大,失败次数加1
			if(base<=arr[low+loseCount])
			{
				loseCount++;
			}
			else
			{
				//比基准值小,置换一次
				swap(arr,low,low+loseCount);
				
				//如果更换的是基准值,记录位置
				if(base==arr[low+loseCount])
				{
					//记录基准值当前的位置
					baseIndex = low+loseCount;
				}
								
				//下一次置换的位置后移一位
				low++;
			}
		}
		
		//基准值置换到分界点
		swap(arr,low,baseIndex);
		
		return low;
	}
	
	/**
	 * 置换数组中2个数的位置
	 * @param arr
	 * @param i
	 * @param j
	 */
	private static void swap(int[] arr,int i,int j)
	{
		if(i!=j)
		{
			int temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
	}
	
	public static void main(String[] args)
	{
		int[] array = {3, 1,-1,20, 203,7,909,5,7, 5, 2, 0,9};
		QuickSort.sort(array);
		
		System.out.println(Arrays.toString(array));
	}
}
运行结果:
[-1, 0, 1, 2, 3, 5, 5, 7, 7, 9, 20, 203, 909]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值