zoukankan      html  css  js  c++  java
  • 【数据结构第八周】排序(下)【快速排序】

    步骤:

    1、从数列中挑出一个元素,称为"基准"或者“主元”(pivot)

    2、重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作

    3、递归地把小于基准值元素的子数列和大于基准值元素的子数列排序

    选主元的时候可以使用“取头、中、尾的中位数”这种方法。

    如果你选取第一个元素作为主元,如果一个数列本身就是有序的,用这种办法产生的O(N^2)的复杂度显然是不能接受的。

    ElementType Median3( ElementType A[], int Left, int Right )
    {
    	int Center=(Left+Right)/2;
    	if ( A[ Left ] > A[ Center ] )
    	{
    		Swap( &A[ Left ], &A[ Center ] );
    	}
    	if (A[ Left ] > A[ Right ])
    	{
    		Swap( &A[ Left ], &A[ Right ] );
    	}
    	if (A[ Center ] > A[ Right ] )
    	{
    		Swap( &A[ Center ], &A[ Right ] );
    	}
    	/* A[ Left ] <= A[ Center ] <= A[ Right ] */
    	Swap( &A[ Center ], &A[ Right-1 ] ); /* 将pivot藏到右边 */ 
        
        /* 只需要考虑 A[ Left+1 ] ... A[ Right–2 ] */
    	return &A[ Right-1 ];
    }
    

    对小规模的数据(例如N不到100)可能还不如插入排序快 。

    解决方案:

    当递归的数据规模充分小,则停止递归,直接调用简单排序(例如插入排序)

    在程序中定义一个Cutoff的阈值

    void Quicksort( ElementType A[], int Left, int Right )
    {
    	if ( Cutoff <= Right-Left ) 
    	{
    		Pivot = Median3( A, Left, Right );
    	
    	    i=Left; j=Right–1;
    	    for( ; ; )
    	    {
    		    while ( A[ ++i ] < Pivot ) { }
    		    while ( A[ ––j ] > Pivot ) { }
    		    if ( i < j )
    		    {
    			   Swap( &A[i], &A[j] );
    		    }else
    		    {
    			    break;
    		    }
    		    Swap( &A[i], &A[ Right-1 ] );
    		    Quicksort( A, Left, i-1 );
    		    Quicksort( A, i+1, Right );
    	    }
    	}else
    	{
    		Insertion_Sort( A+Left, Right-Left+1 );
    	}
    
    }
    
  • 相关阅读:
    【HTML】添加网页背景音乐
    无线安全之破解WPA/WPA2 加密WiFi
    基于deepin-wine的windows软件打包deb安装包教程
    deepin V20 启用Nvidia驱动方法
    [Liunx]Linux安装screenfetch
    开往-友链接力
    linux常用命令(六)提权和文件上传下载的操作
    抓住会员!奇点云DataNuza重大发布
    喜讯 | 奇点云入选「GMIC 2020 PRO 十佳新生代」榜单
    数据智能应用最终实现企业降本增效
  • 原文地址:https://www.cnblogs.com/acmsummer/p/4332554.html
Copyright © 2011-2022 走看看