java编程题:用Java实现一个快速排序算法

import java.util.Arrays;


/**
 * java编程题:用Java实现一个快速排序算法
 * 
 * 快速排序是对冒泡排序的一种改进。
 * 
 * 快速排序的基本思想: 通过一趟排序将要排序的数据分成独立的两部分,其中一部分的所有数据(左边的数据)都比
 * 另外一部分的所有数据(右边的数据)都要小,然后再按此方法对这两部分数据分别进行快速排序, 整个排序过程可以递归进行,以此达到整个数据变成有序的序列。
 * 
 * 一趟快速排序: 在要排序的数据中,首先任意选取一个数据(通常选用第一个数)作为关键数(或称为基准数),
 * 然后将所有比它小的数都放在前面(左边),所有比它大的数都放到后面(右边),这个过程称为一趟排序。
 * 
 * 一趟快速排序规则: 1)设置两个变量i、j,排序开始的时候:i=0,j=N-1; 2)以第一个数组元素作为关键数据(即基准数),赋值给key,即
 * key=A[0]; 3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],A[i]与A[j]交换;
 * 4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],A[i]与A[j]交换; 5)重复执行第3、4步,直到 i=j;
 * 6)到此找到基准点的下标,作为分治下标; 7)重复1-6步骤递归排序前半部分; 8)重复1-6步骤递归排序后半部分。
 * 
 */
public class Test14 {


	public static void main(String[] args) {
		int[] sortNum = new int[]{12,10,-1,15,4,0,-3,16,8,2,33,7,28,19}; 	// 定义数组
		System.out.println("排序前:" + Arrays.toString(sortNum)); 		// 排序前的数组
//		quickSort(sortNum, 0, sortNum.length - 1); 						// 执行排序方法1
		quickSort2(sortNum, 0, sortNum.length - 1); 					// 执行排序方法2
		System.out.println("排序后:" + Arrays.toString(sortNum)); 		// 排序后的数组
	}


	/**
	 * 快速排序方法,写法一
	 *  
	 * @param sortNum
	 *            待排序的原始数组
	 * @param L
	 *            比基准元素都要小的元素下标,左下标
	 * @param R
	 *            比基准元素都要大的元素下标,右下标
	 */
	private static void quickSort(int[] sortNum, int L, int R) {
		
		if (L >= R || sortNum.length<=0) { // i大于或等于j,直接返回
			return;
		}
		
		int i = L; // i,左下标
		int j = R; // j,右下标
		int key = sortNum[L]; // 基准元素,默认取数组的第一个元素


		// 让数组中的全部元素都比较
		while (true) {
			// j往前走
			while (j > i) {
				if (sortNum[j] < key) { // 找到第一个小于key的值A[j],A[i]与A[j]交换
					int temp = sortNum[j];
					sortNum[j] = sortNum[i];
					sortNum[i] = temp;
					break;
				} else {
					j--;
				}
			}


			// i往后走
			while (j > i) {
				if (sortNum[i] > key) { // 找到第一个大于key的A[i],A[i]与A[j]交换
					int temp = sortNum[j];
					sortNum[j] = sortNum[i];
					sortNum[i] = temp;
					break;
				} else {
					i++;
				}
			}


			// 终结最外层while循环,表示一趟排序结束(全部元素都进行了比较)
			if (i == j) {
				break;
			}
		}


		// 继续排序基准元素的左边元素
		quickSort(sortNum, L, i - 1);


		// 继续排序基准元素的右边元素
		quickSort(sortNum, i + 1, R);


	}


	/**
	 *
	 * 快速排序方法,写法二
	 * 
	 * 基本思想:把整个序列看做一个数组,把第一个位置看做中轴,和最后一个比,如果比它小交换,比它大不做任何处理;
	 * 交换了以后再和小的那端比,比它小不交换,比他大交换。这样循环往复,一趟排序完成,左边就是比中轴小的,
	 * 右边就是比中轴大的,然后再用分治法,分别对这两个独立的数组进行排序。
	 * 
	 * @param sortArray	待查找的数组
	 * @param left	下标的开始位置
	 * @param right	下标的结束位置
	 * @return 中轴所在的位置
	 */
    private static int getMiddle(int[] sortArray, int left, int right){  
        int key = sortArray[left];	//以数组的第一个数作为中轴
        
        while(left < right){
        	//从右边开始
            if(sortArray[right] >= key){  
            	right--;		//下标向左移动
            }  
            sortArray[left] = sortArray[right];			//比中轴数小,移动到左边位置,此时left位相当于空,等待低位比key大的数补上
            
            //从左边开始
            if(sortArray[left] <= key){  
            	left++;  		//下标向右移动
            }  
            sortArray[right] = sortArray[left];  		//比中轴数大,移动到右边位置,此时left位相当于空,等待高位比key小的数补上
        }
        
        sortArray[left] = key;  //当left == right,完成一趟快速排序,此时left位相当于空,等待pivotkey补上
        
        return left;			//返回中轴的位置,为什么返回的是left这个位置?当然也可以返回right位置,因为走到最后left与right相同了
    }
    
    //快速排序方法
    public static void quickSort2(int[] sortArray, int left, int right){  
        if(left < right){  
            int middle = getMiddle(sortArray, left, right);  	//中轴数将数组进行一分为二
            quickSort2(sortArray, left, middle-1);  			//比中轴小的左边部分数组继续进行递归排序
            quickSort2(sortArray, middle+1, right);  			//比中轴大的右边部分数组继续进行递归排序
        }  
    }
	
}



参考:
http://blog.csdn.net/gg543012991/article/details/52015181
http://blog.csdn.net/happy_wu/article/details/51841244
http://blog.csdn.net/qarkly112649/article/details/35794097
http://blog.csdn.net/kindterry/article/details/6581358
http://blog.csdn.net/qy1387/article/details/7752973
http://blog.csdn.net/ouyang_peng/article/details/46621963

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值