快速排序

内部排序04——快速排序

原理:1.选取中枢元素
    2.i从左向右扫描,如果小于中枢,则自增,否则记为a[i]
    3.j从右向左扫描,如果大于中枢,自减,否则记为a[j]
    4.交换a[i]和a[j]
    5.重复直到ij交错,之后和基准元素比较,之后交换

 

复杂度:最好O(nlogn)

                最坏:n^2/2

速度比归并排序要快

采用分治解法来求解,就地排序,非稳定。在编程语言中对数组、列表的排序,一般用快排。

 

Java实现

    public void sortColors(int[] nums) {
        //快排就是找start, end,然后确定枢纽,之后比较,换
        quickSort(nums,0,nums.length-1);

    }

    public void quickSort(int[] nums, int start,int end){
        if(start == end) return;
        if(start < end){
            int index = patition(nums, start, end); //找到分区
            quickSort(nums,start,index-1);
            quickSort(nums,index+1,end);
        }
    }

    public int patition(int[] nums, int start,int end){
        if(start == end) return start;
        int index= nums[start]; //选第一个元素作为判断枢纽

        while (start < end){
            //先从后往前找第一个小于枢纽的值
            while (start < end && nums[end] > index){
                end--;
            }
            nums[start] = nums[end];


            //找到前半段,第一个大于枢纽的值
            while (start < end && nums[start] <= index){
                start++;
            }
            nums[end] = nums[start];
        }
        //start==end的时候,就表示本轮ok,把枢纽放到end或者start,作为新的枢纽
        // 因为枢纽选的是start,所以 index start end ,
        // nums[end]放到了start,nums[start]放到了end,那么start或者end退出时的值为空啊,所以就放index
        nums[end] = index;
        return end;
    }

    public static void main(String[] args) {
        int[] nums = {2,0,2,1,1,0};
        new L75_Sort_Colors().sortColors(nums);
        Utils.printArr(nums);
    }

 

/**********************************************************
名称:快速排序
原理:
	1.选取中枢元素
	2.i从左向右扫描,如果小于中枢,则自增,否则记为a[i]
	3.j从右向左扫描,如果大于中枢,自减,否则记为a[j]
	4.交换a[i]和a[j]
	5.重复直到ij交错,之后和基准元素比较,之后交换

***********************************************************/

#include"stdafx.h"
#include<iostream>
using namespace std;

int  Divide(int a[],int first,int last)//选枢纽,划分
{
	int i =first,j = last + 1;
	while(true)
	{
		//从左向右扫描,碰到小于枢纽的,i自增,否则退出循环准备交换
		while(a[++i] < a[first])
		{
			if(i == last) break;//如果扫描到了最右端,退出循环
		}
		//从右向左扫描,碰到小于枢纽的,j自减,否则退出循环准备交换
		while(a[--j] > a[first])
		{
			if(j == first) break;//如果扫描到了最左端,退出循环
		}
		 //如果相遇,退出循环
        if (i >= j) break;
		 //交换左a[i],a[j]右两个元素,交换完后他们都位于正确的分区
        swap(a[i],a[j]);
	}
	//经过相遇后,最后一次a[i]和a[j]的交换
    //a[j]比a[first]小,a[i]比a[first]大,所以将基准元素与a[j]交换
	swap(a[first],a[j]);
	return j;
}

void QuickSort(int a[] ,int first,int last)
{
	if(first >= last)//如果子序列为1,则直接返回
		return;
	int index = Divide(a,first,last);//划分序列,左小于a[index]小于右
	QuickSort(a,first,index-1);//对左子序列排序
	QuickSort(a,index+1,last);//对右子序列排序

	
}
int main()    
{    
    int length = 0;    
    int i = 0;    
    cout << "请输入排序数组长度:" << endl;    
    cin >> length;    
    int a[100] = {0};    
    
    cout << "请输入排序数组:" << endl;    
    for(;i!=length;i++)    
        cin>>a[i];   

    cout << "快速排序:" << endl;    
    QuickSort(a,0,length-1); 
	 for(int i = 0;i!= length;i++)    
    {    
        cout << a[i]<<" ";    
    }    
    cout << endl;    
    
    system("pause");    
    return 0;    
    
}    


 

 

 

 

#include<iostream>
using namespace std;

int Partition(int a[],int start,int end)
{

<span style="white-space:pre">	</span>if(a == NULL || start <0 || end <0)
<span style="white-space:pre">		</span>throw new std::exception("Invalid parameters");
	int index =a[start];
	while(start < end)
	{
		while(start<end && a[end]>index)
			end--;
		if(start < end)
			a[start++] = a[end];

		while(start<end && a[start]<index)
			start++;
		if(start < end)
			a[end--] = a[start];
	}
	a[start] = index;
	return start;
}

void  Qsort(int arr[],int start,int end)
{
	if(start == end)return;
	if(start < end)
	{
		int index = Partition(arr,start,end); 
		Qsort(arr,start,index-1);
		Qsort(arr,index+1,end);
		
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int a[7] = {5,2,4,3,7,9,8};
	Qsort(a,0,6);
	int j = 0;
	while(j!= 7)
		{
			cout << a[j] << " ";
			j++;
	}
	cout <<endl;
	system("pause");
	return 0;
}

 

 

 

 

 

 

参考资料:http://www.cnblogs.com/yangecnu/p/Introduce-Quick-Sort.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值