Java实现数组的快速排序(快速排序算法)

实现快速排序算法的关键在于先在数组中选择一个数字,接下来把数组中的数字分为两部分,比选择数字小的数字移动到数组的左边,比选择数字大的数字移动到数组的右边。
具体的实现算法为:
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个元素)作为基准点,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序,然后采用递归调用,分别以同样的方式排序前面和后面的数据。
值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是: 
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1; 
2)以第一个数组元素作为基准点。 
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于A[i](此时基准点)的值A[j],将值与A[j]交换; 
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于A[j](此时基准点)的A[i],将A[j]与A[i]交换; 
5)重复第3步 
6)重复第3、4、5步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[j]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束),到此找到基准点的下标,作为分治下标。 
7)重复1-6步骤递归排序前半部分 
8 )重复1-6步骤递归排序后半部分 
实现图解:
 
可以采用两种写法来实现此算法:
(1)在进行i++和j--时可以设置一个标志位flag,通过改变flag值为true或false来实现i的连续移动或j的连续移动;
(2)使用while循环,通过判断sortArray[high]、sortArray[low]与key的大小来实现前序遍历或后续遍历。

从键盘输入数组的方法:  
(1)使用   Scanner  sc  =  new  Scanner(System. in );     扫描从键盘的输入
(2)使用          String  str  =  sc .nextLine();   将输入转化为字符串
(3)使用        String[]  temp  =  str .split( " " );  ,通过split()方法将字符串转化为字符串数组
(4)使用       s [i] = Integer.parseInt(temp[i]);   将字符数组转化为整数数组    


程序实现:
/**************************************************************      
* Copyright (c) 2016, 
* All rights reserved.                   
* 版 本 号:v1.0                   
* 题目描述:快速排序算法,从键盘输入一组整数数组,用快速排序输出排序后的结果
* 输入描述:请输入要排序的数组: 
*           48 15 24 59 64 79 97 40
* 程序输出: 48 15 24 59 64 79 97 40
*			输入的数组是:
*			48 15 24 59 64 79 97 40 
*			排序后的数组是:
*			15 24 40 48 59 64 79 97 
*			第二种写法的输出:
*			排序后的数组是:
*			15 24 40 48 59 64 79 97 
* 问题分析:1.从键盘输入一个整数字符串,将字符串转化为整数数组
*       	解决方法:先将字符串用str.split()转化为字符串数组,再将字符串数组转化为整数数组
* 算法描述:实现快速排序算法的关键在于现在数组中选择一个数字,接下来把数组中的数字分为两部分,比选择的数字小的数字移到数组左边,
* 			比选择的数字大的数字移到数组的右边。
* 			1.	设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个元素)作为基准点,然后将所有比它小的数都放到它前面,
* 			所有比它大的数都放到它后面,这个过程称为一趟快速排序,然后采用分治策略,分别以同样的方式排序前面和后面的数据。
*			2.一趟快速排序的算法是: 
*			1)设置两个变量i、j,排序开始的时候:i=0,j=N-1; 
			2)以第一个数组元素作为基准点。 
			3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于A[i](此时基准点)的值A[j],将值与A[j]交换; 
			4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于A[j](此时基准点)的A[i],将A[j]与A[i]交换; 
			5)循环执行第3、4步,直到i=j; 
			6)到此找到基准点的下标,作为分治下标。 
			7)重复1-6步骤递归排序前半部分 
			8 )重复1-6步骤递归排序后半部分 

* 完成日期:2016-07-24
***************************************************************/  
 

package org.marsguo.offerproject;

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
class Sort_Array{
	//int[] s;
	//int i,j,key;
	/*构造函数,用于输出用户输入的数组*/
	public Sort_Array(int[] s){					
		System.out.println("输入的数组是:");
		for(int i = 0; i <s.length; i++){
			System.out.print(s[i] + " ");
		}
		System.out.println();
	}
	/*排序函数,参数为要排序的数组、数组的起始,数组的末尾*/
	public void sortfun(int[] arrays,int start, int end){
		
		if(start>=end){								//判断数组的起始和终止是否相同,相同表示已经都全部排完,返回
			return;
		}
		int i = start;								//i指向数组的起始位
		int j = end;								//j指向数组的末位
		int key = arrays[i];						//选取数组的第一位为关键字key,基准元素
		boolean flag = true;						//设置标志位,用于判断是i++还是j--;这个很重要
		//int temp;
		while(i != j){								//如果i≠j,表示还没有比较完,即即关键字左右两侧还不是最小与最大
			if(flag){					
				if(key>arrays[j]){					//从后向前遍历,找到小于key的值,
					swap(arrays,i,j);				//找到小于key的值后将arrays[i]与此值交换
					flag = false;
				}else{								//如果没有找到的话j--,向前遍历
					j--;
				}
			}else{								
				if(key<arrays[i]){					//从前向后遍历,找到大于key的值
					swap(arrays,i,j);				//将此值与arrays[j]进行交换
					flag = true;
				}else{								//如果没有找到话就将i++,向后遍历
					i++;
				}
			}
		}
		sprint(arrays);								//打印每次排序后的数组
		sortfun(arrays,start,j-1);					//递归调用,将基准元素的前半段数组再用此方法进行排序,直到所有都排完为止。
		sortfun(arrays,i+1,end);					//递归调用,将基准元素的后半段数组再用此方法进行排序,直到所有都排完为止。
//		sortfun(s[0],s[j],s[0]);
//		sortfun(s[j+1],s[s.length-1],s[j+1]);
	}
	/*交换函数,用于交换数组中的两个值,easy,*/
	public void swap(int[] array,int i,int j){			
		int temp;
		temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
	/*sprint()函数用于打印每次排序后的结果,非必须,但可以显示每次排序情况*/
	public void sprint(int[] arrays){			
		System.out.println("排序后的数组是:");
		for(int i = 0; i <arrays.length;i++){
			System.out.print(arrays[i] + " ");
		}
		System.out.println(); 
	}
	
	/*第二种写法:*/
	private int getMiddle(int[] sortArray,int low,int high){
		int key = sortArray[low];
		while(low<high){
			while(low <high && sortArray[high] >= key){
				high--;
			}
			sortArray[low] = sortArray[high];
			while(low < high && sortArray[low] <= key){
				low++;
			}
			sortArray[high] = sortArray[low];
		}
		sortArray[low] = key;
		return low;
	}
	public void quicksort(int[] sortArray, int low,int high){
		if(low<high){
			int middle = getMiddle(sortArray, low, high);
			quicksort(sortArray, low, middle-1);
			quicksort(sortArray, middle+1, high);
		}
		System.out.println("第二种写法的输出:");
		sprint(sortArray);
	}
}
public class Quick_sort {
	public static void main(String args[]){
	Scanner sc = new Scanner(System.in);			//从键盘输入数组
		System.out.println("请输入要排序的数组:");
		String str = sc.nextLine();						//将键盘输入转化为字符串
		String[] temp = str.split(" ");					//将字符串用“ ”分开转化为字符串数组
		int[] s = new int[temp.length];					//定义一个整型数组s
		for(int i = 0; i<temp.length; i++){				//将字符串数组强制转化为整型数组
			s[i] = Integer.parseInt(temp[i]);			//这种方法非常巧妙
		}
		Sort_Array sort_array = new Sort_Array(s);		//创建对象,并传入数组s
		sort_array.sortfun(s, 0, s.length-1);			//调用类的方法,用于排序数组
	
		Sort_Array quickSort = new Sort_Array(s);
		quickSort.quicksort(s, 0, s.length-1);
		
		/*用集合的方法输入不定长数组:
		Scanner scanner = new Scanner(System.in);			//创建输入扫描器
		System.out.println("请输入要排序的数组:");
		List  list = new LinkedList();
		while(scanner.hasNext()){						//循环,当扫描到有下一个元素的时候
			int elements = scanner.nextInt();				//获得下一个元素并作为整数
			if(elements == 0){								//如果等于0,则输入结束
				break;									//退出while循环
			}else{
				list.add(elements);						//否则放入集合中
			}
		}
		Integer[] intArray =  list.toArray(new Integer[0]);
		for(int i = 0; i<intArray.length;i++){
			System.out.println(intArray[i]);
		}
	*/
	}
}



  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值