您的位置:首页 > 编程语言 > Java开发

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

2017-03-23 14:32 369 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐