快速排序---java实现

一  快排的java实现(可以参考大话数据结构里面的内容)

package ch04;

public class QuickSort {
	/**
	 * 快排的基本思想:通过一趟排序将待排记录分割成独立的两部分
	 *  其中一部分的关键字比例外一部分记录的关键字要小
	 *  再,分别对这两部分进行排序
	 * 
	 */
	public static void quickSort(int []arr, int low, int high){
		if(low>high){
			return;
			
		}else{
			int p=partition(arr,low,high);//将数组 分成两部分 
			
			quickSort(arr,low,p-1);   //对低子表递归排序
			quickSort(arr, p+1, high);//对高字表递归排序
		}
	}

	public static int partition(int[] arr, int low, int high) {
		int pivotkey;
		pivotkey=arr[low];//字表的第一个记录做枢轴记录 
		
		while(low<high){//从表的两端交替向中间扫描
			
			while(low<high && arr[high]>=pivotkey)
				high--;
			swap(arr,low,high);    //将比pivotkey小的交换到低端
			
			while(low<high && arr[low]<=pivotkey)
				low++;
			swap(arr,low,high);   //将比pivotkey大的交换到高端
		}
		return low;
	}

	public  static void swap(int[] arr, int low, int high) {
		int temp=arr[low];
		arr[low]=arr[high];
		arr[high]=temp;
		
	}
	public static void main(String[] args) {
		int arr[]={3,95,0,-11,7,2,6};
		quickSort(arr, 0, arr.length-1);
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+" ");
		}
	}
}

二  快排的优化

   pivotkey=arr[low]  将导致总是固定选取 第一个关键字 ,导致性能瓶颈

 (1) 通过三数取中  保证pivotkey是一个中间数,加入几行代码即可

package ch04;

public class QSort {
	/**
	 * 快排的优化
	 */
	public static void quickSort(int []arr, int low, int high){
		if(low>high){
			return;
			
		}else{
			int p=partition(arr,low,high);
			quickSort(arr,low,p-1);
			quickSort(arr, p+1, high);
		}
	}

	public static int partition(int[] arr, int low, int high) {
		int pivotkey;
//
		int mid=low+(high-low)/2;
		
		if(arr[low]>arr[high])   swap(arr,low,high);
		if(arr[mid]>arr[high])   swap(arr,high,mid);
		if(arr[mid]>arr[low])   swap(arr,low,mid);//此时 arr[low]是左中右 三个关键字的中间值
///
		pivotkey=arr[low];//字表的第一个记录做枢轴记录 
		
		while(low<high){//从表的两端交替向中间扫描
			
			while(low<high && arr[high]>=pivotkey)
				high--;
			swap(arr,low,high);
			
			while(low<high && arr[low]<=pivotkey)
				low++;
			swap(arr,low,high);
		}
		return low;
	}

	public  static void swap(int[] arr, int low, int high) {
		int temp=arr[low];
		arr[low]=arr[high];
		arr[high]=temp;
		
	}
	public static void main(String[] args) {
		int arr[]={3,95,0,-11,7,2,6};
		quickSort(arr, 0, arr.length-1);
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+" ");
		}
	}
}

(2)对于较少记录的排序,用插入排序

public static void quickSort(int []arr, int low, int high){
		
		if(high-low>7){//也有资料说取50更合理
			int p=partition(arr,low,high);
			quickSort(arr,low,p-1);
			quickSort(arr, p+1, high);
		}else{
			insertSort(arr);
		}
	}

(3)使用尾递归优化(可以缩减堆栈深度)

 

quickSort(arr, p+1, high);     这句话可以用循环进行替代

最后代码如下

package ch04;

public class QSort {
	/**
	 * 快排的优化
	 */
	public static void quickSort(int []arr, int low, int high){
		int p;
		if(high-low>7){//也有资料说取50更合理
			while(low<high){
				 p=partition(arr,low,high);
				quickSort(arr,low,p-1);
			
				low=p+1;     
			}
		
		}else{
			insertSort(arr);
		}
	}

	
	public static int partition(int[] arr, int low, int high) {
		int pivotkey;
//
		int mid=low+(high-low)/2;
		
		if(arr[low]>arr[high])   swap(arr,low,high);
		if(arr[mid]>arr[high])   swap(arr,high,mid);
		if(arr[mid]>arr[low])   swap(arr,low,mid);//此时 arr[low]是左中右 三个关键字的中间值
///
		pivotkey=arr[low];//字表的第一个记录做枢轴记录 
		
		while(low<high){//从表的两端交替向中间扫描
			
			while(low<high && arr[high]>=pivotkey)
				high--;
			swap(arr,low,high);
			
			while(low<high && arr[low]<=pivotkey)
				low++;
			swap(arr,low,high);
		}
		return low;
	}

	
	public static void insertSort(int []arr){
		int temp=0;
		for(int i=1;i<arr.length;i++){//比较length-1次
			
			temp=arr[i];
			int j=i-1;
			while(j>=0 && temp<arr[j]){//如果第二个元素小于第一个元素
				arr[j+1]=arr[j];//将元素往后面移动一位
				j--;
			}
			arr[j+1]=temp;//最小的元素放到第一个位置
		}
	}
	
	
	public  static void swap(int[] arr, int low, int high) {
		int temp=arr[low];
		arr[low]=arr[high];
		arr[high]=temp;
		
	}
	public static void main(String[] args) {
		int arr[]={3,95,0,-11,7,2,6};
		int arr1[]={3,95,0,-11,7,2,6,89,70,77,123,57,90};
		quickSort(arr, 0, arr.length-1);
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+" ");
		}
		
		System.out.println();
		quickSort(arr1, 0, arr1.length-1);
		for (int i = 0; i < arr1.length; i++) {
			System.out.print(arr1[i]+" ");
		}
	}
}

 

       

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值