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

    快速排序的基本思想是基于分治策略的,其算法思想如下:

    1.分解:先从数列中取出一个元素作为基准元素看,以基准元素为标准,

    将问题分解为两个子序列,使小于或等于基准元素的子序列在左侧,使大于基准元素的子序列在右侧。

    2.治理:对两个子序列进行快速排序。

    3.合并:将排好序的两个子序列合并在一起,得到原问题的解。

    (1)分解:

    选取第一个数作为pivot,设置两个指针low,high,意思即为R[low:high]

    指针从左开始扫描,若是R[low]<=pivot,则指针low右移,若遇到R[low]>pivot,R[low]的值和R[high]的值交换,

    同时,high指针向左移动,此时继续比较low指针与pivot大小关系。重复上述动作,这样一来,R[low]和pivot

    每比较一次就会有指针移动,要么是low右移要么是high左移,最终的结果一定是low和high重合。

    返回该位置mid=i;该位置正好是pivot元素。上代码:

    int partition(int r[],int low,int high)
    {
        int i=low,j=high,pivot=r[low];
    
        while(i<j)
            {
                if(r[i]<pivot)
                    i++;
                else
                    swap(r[i],r[j--]);
            }
        swap(r[low],r[j]);
        return j;
    }
     

    当然,还有另一种思路:

    int Partition(int r[],int low,int high) 
    {
    	int i=low,j=high,pivot=r[low];
    	while(i<j)
    	{
    		while(i<j&&r[j]>pivot)
    		{
    			j--;
    		}
    		if(i<j)
    		{
    			swap(r[i++],r[j]);
    		}
    		while(i<j&&r[i]<=pivot)
    		{
    			i++;
    		}
    		if(i<j)
    		{
    			swap(r[i],r[j--]);
    		}
    	}
    	return j;
    }

    两中方法结果是一样的。

    2.快速排序递归算法:

    首先对原序列执行划分,得到划分的中间位置mid,然后以中间位置为边界,分别对左半部分(low,high-1)执行快速排序,右半部分(mid+1,high)执行快速排序。递归条件是low>=high.

    void QuickSort (int R[],int low,int high)
    {
    	int mid;
    	if(low<high)
    	{
    		mid=Partition(R,low,high);//返回基准元素位置 
    		QuickSort(R,low,mid-1);//左区间递归快速排序 
    		QuickSort(R,mid+1,high);//右区间递归快速排序 
    	}
    }

    快速排序算法平均情况下,时间复杂度为O(nlogn),递归调用所使用的栈空间也是O(logn);

    优化算法:

    int Partition2(int r[],int low,int high) 
    {
    	int i=low,j=high,pivot=r[low];//基准元素
    	while(i<j) 
    	{
    		while(i<j&&r[j]>pivot) i--;//向左扫描
    		while(i<j&&p[i]<=pivot)  i++;//向右扫描
    		if(i<j) 
    		{
    			swap(r[i++],r[j--]); 
    		}
    	}
    	if(r[i]<pivot)
    	{
    		swap(r[i-1],r[low]);
    		return i-1;
    	}
    	swap(r[i],r[low]);
    		return i;
    }

    进一步优化:因为以上快速排序算法每次只能返回一个值,比如上一个算法返回的是i,那么如果一次返回多个值,会不会更快呢。

    public  int[] partition(int[] arr, int l, int r) {
    		int less = l - 1;
    		int more = r;
    		while (l < more) {
    			if (arr[l] < arr[r]) {
    				swap(arr, ++less, l++);
    			} else if (arr[l] > arr[r]) {
    				swap(arr, --more, l);
    			} else {
    				l++;
    			}
    		}
    		swap(arr[more],arr[r]);
    		return  int[] { less + 1, more };
    	}
  • 相关阅读:
    Description Resource Path Location Type Java compiler level does not match the version of the instal
    myeclipse导入项目后,项目类中报Base64错
    Oracle中查询一个字符串的长度的函数
    异常QueryTimeoutException和for input String
    myeclipse中的内存溢出PermGen space
    SecureCRT--下重启服务器
    清除tomcat的缓存
    oracle 定时任务 job 调用存储过程有回到输出参数(含out参数)
    Spring之AOP
    @RequestParam、@PathVariable、@RequestBody区别
  • 原文地址:https://www.cnblogs.com/chmusk/p/11078922.html
Copyright © 2011-2022 走看看