排序算法--快速排序

    快速排序是运用分治思想的一种性能优良的排序方法,之所以被叫做快速排序是因为它的排序速度非常的快,当然这只是相对某种情况而言的,不过我们仍可以说快速排序是实践当中已知的最快的排序算法.

    快速排序的算法是假设有一个数组A[n],首先将这个数组划分为A[1....x]和A[x + 1.......n]两个数组,并且是前一个数组的所有元素都不大于后一个数组的元素.然后再分别对两个数组递归的使用上面的方法排序.因为数组是原地排序的,所以分治中的合并这一步就不需要了.

代码:

 

#include  < stdio.h >

const   int  MAX  =   10 ;

int  Partition( int   * A,  int  low,  int  high)
{
    
int temp, i, j, a;
    a 
= A[low];
    i 
= low - 1;
    j 
= high + 1;
    
while(1)
    
{
        
do
            j 
-= 1;
        
while(A[j] > a);
        
        
do
            i 
+= 1;
        
while(A[i] < a);
        
if(i < j)
        
{
            temp 
= A[i];
            A[i] 
= A[j];
            A[j] 
= temp;
        }

        
else
            
return j;
    }

}


void  quickSort( int   * A,  int  low,  int  high)
{
    
int position;
    
if(low < high)
    
{
        position 
= Partition(A, low, high);
        quickSort(A, low, position);
        quickSort(A, position 
+ 1, high);
    }

}


int  main()
{
    
int A[MAX];
    
int i;
    
int nums = MAX;
    printf(
"Please input %d numbers: ", nums);
    
for(i = 0; i < MAX; i++)
        scanf(
"%d"&A[i]);
    quickSort(A, 
0, MAX - 1);
    
for(i = 0; i < MAX; i++)
        printf(
"%d ", A[i]);
    
return 0;
}

 

    就像是希尔排序的关键是增量数列一样,快速排序也有影响效率的关键,那就是数组的输入和划分.

    假设有一个乱序的文件,致使快速排序每次划分的时候都可以将整个数组平均的分成n / 2,这样的话,我们就可以计算得到运行时间是T(n) = 2T(n / 2) + Θ(n),实际上就是Θ(nlog2n).

     如果假设有一个几乎排好序或者是几乎反序的数组,那么运行时候划分情况是相当糟糕的, 几乎每一步都是最不对称的划分,此时的运行时间是Θ(n2) ,而此时的插入排序只需要O(n)的时间.所以快速排序是一个喜欢乱文件的排序算法.

    为了解决上面的问题,可以有许多的方法,其中有一种方法就是随机的交换一些数据,消除接近有序的文件所带来的恶果.

代码:

 

#include  < stdio.h >
#include 
< stdlib.h >
#include 
< time.h >

const   int  MAX  =   10 ;

int  Partition( int   * A,  int  low,  int  high)
{
    
int temp, i, j, a;
    a 
= A[low];
    i 
= low - 1;
    j 
= high + 1;
    
while(1)
    
{
        
do
            j 
-= 1;
        
while(A[j] > a);
        
        
do
            i 
+= 1;
        
while(A[i] < a);
        
if(i < j)
        
{
            temp 
= A[i];
            A[i] 
= A[j];
            A[j] 
= temp;
        }

        
else
            
return j;
    }

}


int  randomPartition( int   * A,  int  low,  int  high)
{
    
int i, temp;
    srand(time(NULL));
    i 
= rand() % (high - low + 1+ low;//rand是随机函数
    temp = A[low];
    A[low] 
= A[i];
    A[i] 
= temp;
    
return Partition(A, low, high);
}


void  quickSort( int   * A,  int  low,  int  high)
{
    
int position;
    
if(low < high)
    
{
        position 
= randomPartition(A, low, high);
        quickSort(A, low, position);
        quickSort(A, position 
+ 1, high);
    }

}


int  main()
{
    
int A[MAX];
    
int i;
    
int nums = MAX;
    printf(
"Please input %d numbers: ", nums);
    
for(i = 0; i < MAX; i++)
        scanf(
"%d"&A[i]);
    quickSort(A, 
0, MAX - 1);
    
for(i = 0; i < MAX; i++)
        printf(
"%d ", A[i]);
    
return 0;
}

 

  按照上面的方法写出的程序在最坏的情况下运行时间仍是Θ(n2),但是这种情况发生的概率已经很小了,对于这样一个算法的平均的运行时间,<<算法导论>>上给出了精确的证明,既是O(nlog2n),

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值