数据结构与算法——快速排序

 

/*——1——*/

void quick_sort(int a[], int left, int right)
{
    if (left < right)
    {
        /* at the beginning, we could choose any element as a pivot element*/
        /*
        int Tmp;
        Tmp = a[right];
        a[right]=a[(left+right)/2];
        a[(left+right)/2]=Tmp;
        */
        int i, j, x;
        x = a[right];// choose the last element as the pivot element
        i = left - 1;// notice that it begins before the first element
        for (j = left; j <= right - 1; j++){ // from the first element to the penultimatter  element
            if (a[j] <= x){  // if the element no larger than the pivot element
                i++;  // save a position for the element
                swap(&a[i], &a[j]);  // put the element in the appropriate position
            }
        }
        swap(&a[i + 1], &a[right]);  // put the pivot element behind all of the elements which are no larger than it
        quick_sort(a, left, i ); // QuickSort the first half   
        quick_sort(a, i + 2, right); // QuickSort the bottom half
    }
}

void swap(int *a, int *b){
    int *Tmp;
    Tmp = a;
    a = b;
    b = Tmp;
}

 

/*——2——*/

/* The following algorithm which comes from http://blog.csdn.net/morewindows/article/details/6684558
utilizes another thought which don't need to swap*/
void quick_sort(int a[], int left, int right)
{
    if (left < right)
    {
        /* at the beginning, we could choose any element as a pivot element*/
        /*
        int Tmp;
        Tmp = a[right];
        a[right]=a[(left+right)/2];
        a[(left+right)/2]=Tmp;
        */
        int i, j, x;
        x = a[right];/* choose the last element as the pivot element*/
        i = left;//the left beginning
        j = right;//the right beginning
        while (i < j){
            /*We could understand the a[right] as a hole because it has been remembered by the x, which means that we could put the element which is larger
            than the pivot element into this hole.
            */
            while (i < j && a[i] < x)  //if we encounter the samller element, just make them stay in the original position.
                i++;
            if (i < j)
                a[j--] = a[i];  // put the larger element into the hole, at that time we would get a new hole
            /*This time we need to seek for the smaller element to fill in the new hole*/
            while (i < j && a[j] > x) // if we encounter the larger element, just make them in the original position
                j--;
            if (i < j) // put the smaller element into the hole, at that time we would get another new hole.
                a[i++] = a[j];
        }
        a[j] = x;  // In the last, we utilize the pivot element to fill in the final hole.
        quick_sort(a, left, j - 1 ); // QuickSort the first half   
        quick_sort(a, j + 1, right);//QuickSort the bottom half
    }
}

 

/*——3——*/
/*This algorithm adopts the  median-of-three partitioning*/

#define Cutoff (3)
void QSort(int a[], int left, int right){
    int i, j;
    int pivot;

    if (left + Cutoff <= right){
        pivot = Median3(a, left, right);// acquire the median as the pivot element
        i = left, j = right - 1;/*here we should notice that the pivot element stays in the penulimatter position,
                                because passing the median-of-three partitioning makes the last element is larger than
                                the pivot element*/
        while (1){
            while (a[++i] < pivot){}/*in the left side,if the element smaller than pivot element, just make it stay*/
            while (a[--j] > pivot){}/*in the right side,if the element larger than pivot element, just make it stay*/
            if (i < j)
                swap(&a[i], &a[j]);
            else
                break;
        }
        swap(&a[i], &a[right - 1]);/*put the pivot into the appropriate position, we should notice that because of i++,j--,at that time,
                                   a[i] is larger than pivot and a[j] is smaller than pivot. Therefore, we exchange a[i] with pivot element */
        QSort(a, left, i - 1);
        QSort(a, i + 1, right);
    }
    else
         InsertionSort(a+left, right - left + 1);
}

int Median3(int a[], int left, int right){
    int center;

    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]);

    swap(&a[center], &a[right - 1]);/*make the penulimatter element become the pivot element, because
                                     the right element is larger than the pivot element*/
    return a[right - 1];
}

posted @ 2016-12-18 09:45  z_Vincent  阅读(172)  评论(0)    收藏  举报