zoukankan      html  css  js  c++  java
  • 快速排序的改进

    package com.txq.test;
    /**
     * quicksort,三方面改进:①三数中值选择枢纽元②容量小的时候使用插入排序③重复元素的处理
     * @author XueQiang Tong
     * @date 2017/10/25
     */
    public class QS {
    	
    	public void quicksort(int []arr,int low,int high){
    		int first = low;
    		int last = high;
    		int left = low;
    		int right = high;
    		int leftLen = 0;
    		int rightLen = 0;
    		//当分割后的容量较小时,使用插入排序,提高性能
    		if(high - low + 1 <= 10){
    			InsertSort(arr,low,high);
    			return;
    		}
    		
    		int key = SelectPivotMedianOfThree(arr,low,high);
    		
    		while(low < high){
    			while(high > low && arr[high] >= key){
    				if(arr[high] == key){//重复元素处理策略:分割过程中把他们放在数组两端,递归调用时掠过他们,提高性能
    					swap(arr,high,right);
    					right --;
    					rightLen ++;
    				}
    				high --;
    			}
    			arr[low] = arr[high];//交换
    			while(high > low && arr[low] <= key){
    				if(arr[low] == key){
    					swap(arr,low,left);
    					left ++;
    					leftLen ++;
    				}
    				low ++;
    			}
    			arr[high] = arr[low];//交换
    		}
    		arr[low] = key;//此时总是low = high,把key放在此位置,一次迭代完成,进入下次递归调用
    		//接下来,把重复元素存储到key的周围
    		int i = low - 1;
    		int j = first;
    		while(j < left && arr[i] != key){
    			swap(arr,j,i);
    			i --;
    			j ++;
    		}
    		i = low + 1;
    		j = last;
    		while(j > right && arr[i] != key){
    			swap(arr,j,i);
    			i ++;
    			j --;
    		}
    		quicksort(arr,first,low - leftLen - 1);
    		quicksort(arr,low + rightLen + 1,last);
    	}
    	/**
    	 * low,mid,high,对三个数排序,arr[mid] <= arr[low] <= arr[high],取arr[low]作为枢纽元
    	 * @param arr
    	 * @param low
    	 * @param high
    	 * @return
    	 */
    	private int SelectPivotMedianOfThree(int[] arr, int low, int high) {
    		int mid = low + ((high - low) >> 1);
    		if(arr[mid] > arr[high]){
    			swap(arr,mid,high);
    		}
    		if(arr[low] > arr[high]){
    			swap(arr,low,high);
    		}
    		if(arr[low] < arr[mid]){
    			swap(arr,low,mid);
    		}
    		return arr[low];
    	}
    
    	public void swap(int arr[],int i, int j) {
    		int tmp;
    		tmp = arr[i];
    		arr[i] = arr[j];
    		arr[j] = tmp;		
    	}
    	/**
    	 * 插入排序
    	 * @param arr
    	 */
    	private void InsertSort(int[] arr,int low,int high) {
    		int i,j;
    		int n = high - low + 1;
    		int target;
    		for(i = low+1;i < low+n;i++){
    			j = i;
    			target = arr[i];
    			while(j > low && target < arr[j-1]){
    				arr[j] = arr[j-1];
    				j--;
    			}
    			arr[j] = target;
    		}		
    	}	
    }
    
  • 相关阅读:
    vba 填写 Workbok 名片
    VBA 插入和删除工作表
    VBA for each 循环语句
    VBA 中的各种循环
    VBA 的 Join 函数
    VBA 计算数组的最大索引和最小索引
    VBA 变量赋值
    VBA 声明变量
    观察样本的变异程度
    python 将数据写入 Excel 表格
  • 原文地址:https://www.cnblogs.com/txq157/p/7728236.html
Copyright © 2011-2022 走看看