快速排序算法多种语言实现

快速排序是一种排序算法,由东尼·霍尔所发展的,以平均性能来说,排序 n 个项目要Θ(n log n)次比较。然而,在最坏的性能下,它需要Θ(n2)次比较。一般来说,快速排序实际上明显地比其他Θ(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项之可能性。

快速排序是二叉查找树(二叉查找树)的一个空间优化版本。不以循序地把项目插入到一个明确的树中,而是由快速排序组织这些项目到一个由递归调用所意含的树中。这两个算法完全地产生相同的比较次数,但是顺序不同。

快速排序的最直接竞争者是堆排序(Heapsort)。堆排序通常比快速排序稍微慢,但是最坏情况的运行时间总是O(n log n)。快速排序是经常比较快,除了introsort变化版本外,仍然有最坏情况性能的机会。如果事先知道堆排序将会是需要使用的,那么直接地使用堆排序比等待 introsort 再切换到它还要快。堆排序也拥有重要的特点,仅使用固定额外的空间(堆排序是原地排序),而即使是最佳的快速排序变化版本也需要Θ(log n)的空间。然而,堆排序需要有效率的随机存取才能变成可行。

快速排序也与归并排序(Mergesort)竞争,这是另外一种递归排序算法,但有坏情况O(n log n)运行时间的优势。不像快速排序或堆排序,归并排序是一个稳定排序,且可以轻易地被采用在链表(linked list)和存储在慢速访问媒体上像是软盘存储网络连接存储的非常巨大数列。尽管快速排序可以被重新改写使用在炼串行上,但是它通常会因为无法随机存取而导致差的基准选择。归并排序的主要缺点,是在最佳情况下需要Ω(n)额外的空间。

于此我们展示在数种语言下的几个快速排序实现。我们在此仅秀出最普遍或独特的一些;针对其他的实现,参见快速排序实现条目。

主条目:快速排序实现

[编辑]C

排序一个整数的数组

void swap(int *a, int *b)
{ 
  int t=*a; *a=*b; *b=t; 
}
 
void quicksort(int arr[],int beg,int end)
{
        if (end  >= beg + 1) 
        {
                int piv = arr[beg], k = beg + 1, r = end;
 
                while (k < r) 
                {
                        if (arr[k] < piv) 
                                k++;
                        else
                                swap(&arr[k], &arr[r--]);
                }
                if (arr[k] < piv){
                        r++;
                        swap(&arr[k],&arr[beg]);
 
                        quicksort(arr, beg, k);
                        quicksort(arr, r, end);                    
                }else {
                        if (end - beg == 1)
                                return;
 
                        swap(&arr[--k],&arr[beg]);
                        quicksort(arr, beg, k);
                        quicksort(arr, r,   end);                  
                }
        }
 
}

另一个版本

void swap(int *a, int *b)
{ 
  int t=*a; *a=*b; *b=t; 
}
void qsort(int arr[],int l,int r)
{
     int i = l;
     int j = r;
     int key = arr[(i+j)/2];
     while(i < j)
        {
            for(;(i < r)&&(arr[i] < key);i++);
            for(;(j > l)&&(arr[j] > key);j--);
            if (i <= j)
               {
                 if ( i != j)
                    { 
                       swap(&arr[i],&arr[j]);
                    }
                 i++;
                 j--;
                }
        }
     if (i < r)
           qsort(arr,i,r);
     if (j > l)
           qsort(arr,l,j);
}

第三个版本

/************************************************************************/
/* 总觉得以上两个版本不对,附上一个版本,真正的快排没有swap的,longrenle*/
/************************************************************************/
void quickSort(int data[], int left, int right)
{
        int temp = data[left];
        int ptr = left;
        int i = left + 1, j = right;
        if(data[i] <= temp)
        {
                data[ptr] = data[i];
                ptr = i;
        }
        while(i!=j)
        {
                if(data[j] >= temp)
                {
                        j--;
                }
                else
                {
                        data[ptr] = data[j];
                        ptr = j;
                        while(data[i] <= temp && i != j)
                        {
                                i++;
                        }
                        data[ptr] = data[i];
                        ptr = i;
                }
        }
        data[ptr] = temp;
        if(left < ptr - 1)
                quickSort(data, left, ptr - 1);
        if(ptr + 1 < right)
                quickSort(data, ptr + 1, right);
}

[编辑]C++

这是一个使用标准模版库(STL)的泛型式快速排序版本。

#include <functional>
#include <algorithm>
#include <iterator>
 
template< typename BidirectionalIterator, typename Compare >
void quick_sort( BidirectionalIterator first, BidirectionalIterator last, Compare cmp ) {
  if( first != last ) {
    BidirectionalIterator left  = first;
    BidirectionalIterator right = last;
    BidirectionalIterator pivot = left++;
 
    while( left != right ) {
      if( cmp( *left, *pivot ) ) {
         ++left;
      } else {
         while( (left != right) && cmp( *pivot, *right ) )
           right--;
         std::iter_swap( left, right );
      }
    }
 
    if (cmp( *pivot, *left ))
         --left;
    std::iter_swap( first, left );
 
    quick_sort( first, left, cmp );
    quick_sort( right, last, cmp );
  }
}
 
template< typename BidirectionalIterator >
inline void quick_sort( BidirectionalIterator first, BidirectionalIterator last ) {
  quick_sort( first, last,
    std::less_equal< typename std::iterator_traits< BidirectionalIterator >::value_type >()
  );
}

[编辑]Java

import java.util.Comparator;
import java.util.Random;
 
public class Quicksort {
    public static final Random RND = new Random();
 
    private static void swap(Object[] array, int i, int j) {
        Object tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
 
    private static <E> int partition(E[] array, int begin, int end, Comparator<? super E> cmp) {
        int index = begin + RND.nextInt(end - begin + 1);
        E pivot = array[index];
        swap(array, index, end);     
        for (int i = index = begin; i < end; ++ i) {
            if (cmp.compare(array[i], pivot) <= 0) {
                swap(array, index++, i);
            }
        }
        swap(array, index, end);     
        return (index);
    }
 
    private static <E> void qsort(E[] array, int begin, int end, Comparator<? super E> cmp) {
        if (end > begin) {
            int index = partition(array, begin, end, cmp);
            qsort(array, begin, index - 1, cmp);
            qsort(array, index + 1,  end,  cmp);
        }
    }
 
    public static <E> void sort(E[] array, Comparator<? super E> cmp) {
        qsort(array, 0, array.length - 1, cmp);
    }
}

[编辑]Perl

sub qsort {
    return () unless @_;
    (qsort(grep { $_ < $_[0]  } @_[1..$#_]),   $_[0],
     qsort(grep { $_ >= $_[0] } @_[1..$#_]));
}

[编辑]Python

def qsort(L):
   if not L: return []
   return qsort([x for x in L[1:] if x< L[0]]) + L[0:1] + \
          qsort([x for x in L[1:] if x>=L[0]])

[编辑]Joy

DEFINE sort == [small][]
               [uncons [>] split]
               [[swap] dip cons concat] binrec .

[编辑]PHP

function quicksort($seq) {
  if (count($seq) > 1) {
    $k = $seq[0];
    $x = array();
    $y = array();
    for ($i=1; $i<count($seq); $i++) {
      if ($seq[$i] <= $k) {
        $x[] = $seq[$i];
      } else {
        $y[] = $seq[$i];
      }
    }
    $x = quicksort($x);
    $y = quicksort($y);
    return array_merge($x, array($k), $y);
  } else {
    return $seq;
  }
}

[编辑]Haskell

  sort :: (Ord a)   => [a] -> [a]
 
  sort []           = []
  sort (pivot:rest) = sort [y | y <- rest, y < pivot]
                      ++ [pivot] ++ 
                      sort [y | y <- rest, y >=pivot]

[编辑]Prolog

split(H, [A|X], [A|Y], Z) :-
  order(A, H), split(H, X, Y, Z).
split(H, [A|X], Y, [A|Z]) :-
  not(order(A, H)), split(H, X, Y, Z).
split(_, [], [], []).
 
quicksort([], X, X).
 
quicksort([H|T], S, X) :-
  split(H, T, A, B),
  quicksort(A, S, [H|Y]),
  quicksort(B, Y, X).

[编辑]Ruby

def sort(array)
  # return [] if array.empty?
  return array if array.size < 2
  left, right = array[1..-1].partition { |y| y <= array.first }
  sort(left) + [ array.first ] + sort(right)
end

[编辑]SML

This example demonstrates the use of an arbitrary predicate in a functional language.

fun quicksort lt lst =
  let val rec sort =
    fn [] => []
     | (x::xs) =>
        let
          val (left,right) = List.partition (fn y => lt (y, x)) xs
        in sort left @ x :: sort right
        end
  in sort lst
end

[编辑]Pascal

program QSort;
const Max = 1000;
var Data: array[1..Max] of integer;
    I: Integer;
 
procedure Sort(l, r: Integer);
var i, j, x, y: integer;
begin
     i := l;
     j := r;
     x := Data[(l+r) DIV 2];
     while i<=j do
     begin
          while Data[i] < x do inc(i);
          while x < Data[j] do dec(j);
          if i <= j then
          begin
               y := Data[i];
               Data[i] := Data[j];
               Data[j] := y;
               inc(i);
               dec(j);
          end;
     end;
     if l < j then Sort(l, j);
     if i < r then Sort(i, r);
end;
 
begin {QSort}
     Randomize;
     for i := 1 to Max do Data[i] := Random(30000);
     Sort(1, Max);
     Writeln;
     for i := 1 to Max do Write(Data[i]:8);
end.

[编辑]C#

       public static void Sort(int[] numbers)
        {
            Sort(numbers, 0, numbers.Length - 1);
        }
 
        private static void Sort(int[] numbers, int left, int right)
        {
            if (left < right)
            {
                int middle = numbers[(left + right) / 2];
                int i = left - 1;
                int j = right + 1;
                while (true)
                {
                    while (numbers[++i] < middle) ;
 
                    while (numbers[--j] > middle) ;
 
                    if (i >= j)
                        break;
 
                    Swap(numbers, i, j);
                }
 
                Sort(numbers, left, i - 1);
                Sort(numbers, j + 1, right);
            }
        }
 
        private static void Swap(int[] numbers, int i, int j)
        {
            int number = numbers[i];
            numbers[i] = numbers[j];
            numbers[j] = number;
        }

[编辑]VB.Net

    Private m_i32ArrSort(10000) As Integer
 
    Private Sub main()
        m_vSorting(1, 10000)
    End Sub
 
    ' Sort
    Private Sub m_vSorting(ByVal i32Left As Integer, ByVal i32Right As Integer)
 
        If (i32Left >= i32Right) Then Return
 
        Dim i32I, i32J As Integer
        Dim i32Middle = m_i32ArrSort(i32Left)
 
        i32I = i32Left + 1
        i32J = i32Right
 
        Do
 
            While (i32I <= i32Right)
                If (m_i32ArrSort(i32I) > i32Middle) Then Exit While
                i32I += 1
            End While
 
            While (i32J > i32Left)
                If (m_i32ArrSort(i32J) < i32Middle) Then Exit While
                i32J -= 1
            End While
 
            If (i32I > i32J) Then Exit Do
 
            m_vSwap(i32I, i32J)
        Loop
 
        m_vSwap(i32Left, i32J)
 
        m_vSorting(i32Left, i32J)
        m_vSorting(i32J + 1, i32Right)
 
    End Sub
 
    ' Swap
    Private Sub m_vSwap(ByVal i32I As Integer, ByVal i32J As Integer)
 
        Dim i32Tmp As Integer = m_i32ArrSort(i32I)
        m_i32ArrSort(i32I) = m_i32ArrSort(i32J)
        m_i32ArrSort(i32J) = i32Tmp
 
    End Sub

 

posted @ 2011-11-29 12:41  seastarcn  阅读(449)  评论(0编辑  收藏  举报