【算法系列】快速排序算法

1. 快速排序算法

快速排序算法是程序员要知道的经典算法之一。快速排序算法,平均时间复杂度为,最坏的时间复杂度为,但是这种概率比较小,可能说这个算法时间复杂度跟归并算法差不多,但为什么还受到这么多人青睐呢,一个重要的原因是它不需要额外的空间进行副本拷贝,是一种原地(in-place)排序算法。从上述大家也可能推算出,快速排序算法的时间复杂度并不是特别统一。确实,这是因为基准“pivot”选择的不同而导致的。那具体什么是pivot呢?又怎么选择pivot呢?

1.1     算法描述:

快速排序算法,采用了分治法的思想。步骤如下:

快速排序处理:

  • 第一步(分):在输入数列中,选择一个元素作为pivot,元素值记为x,使得整个数列由两部分A和B组成,满足A = {a | a <= x}且B={b|b>=x};
  • 第二步(治):分别对A和B递归快速排序处理。
  • 第三步(合):无此步骤,忽略。

 

算法伪代码如下:

Partition(A, p,  q)  // A[p, …, q]

        x ← A[p]     // pivot = A[q]

        i ← p

       for j ← p+1 to q

           do if A[j] <= x

                 than i ← i+1

                         swap(A[i+1], A[j]) 

       swap( A[p], A[i])

       return i;

 

quicksort(A,p, q)

   if p < q

   than r ← Partition(A, p, q)

        quicksort(A,p, r-1)

        quicksort(A,r+1, q)

Init call :quicksort(A, 1, n)

 

1.2     算法执行过程


(图片来源于维基百科)

1.3     时间复杂度


此处可以发现,当对于特定数列输入A时,若每次运算r是一个固定值时,快速排序算法的运行时间是一个确定的值, 但此时有可能低于平均时间复杂度,也有可能高于。如果对于相同数列的输入,要使得算法的时间复杂度不取决于数列输入顺序的话,就必须要求基准pivot必须取得足够的聪明,即随机选取pivot。

这样即使对于相同的输入,运行10000000000次排序,每一次的pivot都有可能不相同,而且最终算法复杂度的期望值趋近于

1.3     C语言实现

static int partition (int array[], int start, int end) 
{
    int pivot = array[start];
    int j=end, i = start;
   
    while (i < j) {
          while ((i < j) && (pivot <= array[j])) {
              j--;
          }
          array[i] = array[j];
          while ((i < j) && (pivot >= array[i])) {
              i++;
         }
         array[j] = array[i];
    }
    array[i] = pivot;
    return i;
}

void quicksort (int array[], int start, int end) 
{
    int r;
	
	if (end > start) {
		r = partition(array, start, end);
		quicksort(array, start, r - 1);
		quicksort(array, r + 1, end);
	}
}


 
 


        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值