• 5. 快速排序


    一、基本思想

    通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以使整个序列有序。

    在分割的过程中,枢纽元的选择至关重要。原因如下:

      (1)两部分数据是以枢纽元为分界点,小于等于枢纽元的数全部放在枢纽元的左边,而大于等于枢纽元的数全部放在枢纽元的右边;

      (2)一般选用左端、右端和中心位置上的三个元素的中值作为枢纽元,即三数取中法,它可以很大程度上避免分组“一边倒”的情况。

    二、三数取中

    在快排的过程中,每一趟排序我们都要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。

    在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。

    三、根据枢纽值进行分割

    四、代码

    /* 快速排序 */ 
    void QuickSort(int a[], int left, int right)
    {
    	if(left >= right)
    		return;
    	
    	// 采用三数取中法,获取枢纽元,并将其放在当前待处理序列末尾 
    	DealPivot(a, left, right);
    	int pivot = a[right-1];			// pivot为枢纽元,而其下标为right-1 
    
    	int i = left, j = right - 1;	// 设置两个游标,用以标记待排序区间
    	// 当 i = j 时,已经查找完整个区间了 
    	while(i != j) {
    		while(i < j && a[i] <= pivot) 	// 因为枢纽元在右边,所以从左边开始 
    			++i;
    		while(i < j && a[j] >= pivot)
    			--j;
    		if(i < j)
    			swap(a[i], a[j]);
    	}
    	// 此时 i = j 
    	swap(a[i], a[right-1]);	
    		
    	sort(a, left, i-1);
    	sort(a, i+1, right);
    }
    
    // 处理枢纽元 
    void DealPivot(int a[], int left, int right)
    {
    	int mid = (left + right) / 2;
    	if(a[left] > a[mid])
    		swap(a[left], a[mid]);
    	if(a[left] > a[right])	
    		swap(a[left], a[right]);
    	if(a[mid] > a[right])
    		swap(a[mid], a[right]);
    	swap(a[mid], a[right-1]);		// 将枢纽元放到倒数第二个元素去,所以要先从左边检索 
    }
    

      

  • 相关阅读:
    中文词语的语法划分
    程序员转行可以做什么?
    Linux Crontab 定时任务 命令详解
    Spring对AOP的支持
    ASP.NET 2.0 Web Part编程入门
    linux ramdom hung up
    VLC plugin加载代码分析
    mac上的ssh proxy客户端 iSSH个人修改版
    关于MP4 fileformat中 duration及timescale相关的几个地方
    inline 小结
  • 原文地址:https://www.cnblogs.com/xzxl/p/9581996.html
Copyright © 2020-2023  润新知