计算Quicksort算法中的基本操作

时间:2017-03-10 05:13:56

标签: c++ sorting

我正在尝试计算Hoare快速排序算法完成的基本操作量。我想知道我是否把柜台放在正确的位置。我的任务是计算100个随机生成的大小为10,100,1k和10k的数组的基本操作数。

这是放置计数器的算法(第6行):

    void QuickSort(int* array, int startIndex, int endIndex, int &counter) {
    int pivot = array[startIndex];                  //pivot element is the leftmost element
    int splitPoint;

    if (endIndex > startIndex)                                                                                      
    {
        counter++; //counting 
        splitPoint = SplitArray(array, pivot, startIndex, endIndex);
        array[splitPoint] = pivot;
        QuickSort(array, startIndex, splitPoint - 1, counter);   //Quick sort first half
        QuickSort(array, splitPoint + 1, endIndex, counter);     //Quick sort second half
    }
}
void swap(int &a, int &b) {
    int temp;
    temp = a;
    a = b;
    b = temp;
}
int SplitArray(int* array, int pivot, int startIndex, int endIndex) {
    int leftBoundary = startIndex;
    int rightBoundary = endIndex;

    while (leftBoundary < rightBoundary)              
    {
        while (pivot < array[rightBoundary]       
            && rightBoundary > leftBoundary)     
        {
            rightBoundary--;                        
        }
        swap(array[leftBoundary], array[rightBoundary]);


        while (pivot >= array[leftBoundary]       
            && leftBoundary < rightBoundary)      
        {
            leftBoundary++;                      
        }
        swap(array[rightBoundary], array[leftBoundary]);            
    }
    return leftBoundary;                              

}

这些结果有意义吗?

Array[Amount]   Array[10]       Array[100]      Array[1k]       Array[10k]
MAX:                 8              72               682        7122
MIN:                 5              63               653        7015
AVERAGE:             6.36           66.54            667.87     7059.41

或者我把柜台放在了错误的地方。

1 个答案:

答案 0 :(得分:0)

柜台在错误的地方。你的任务是计算基本操作。排序的基本操作是什么?通常,我们会计算比较操作的数量,以衡量排序的复杂性。

我们知道QuickSort平均为O(N Log N),其中N是被排序的项目数,而最坏的情况是O(N ^ 2)。

您的数字小于N,这是不可能的,因为N个项目中的每一个必须至少与其他元素进行一次比较,排序成本不能低于N(否则至少有一个元素不能与任何东西,所以你不能保证它被分类了。

在算法中,将数组的元素与数据透视值进行比较时会发生比较操作。因此,每次将数组元素与Pivot进行比较时,都要递增计数器。您的测量数字应至少为N,通常约为N * log N,很少接近N ^ 2.

请参阅下面 SplitArray 增加计数器的位置:

    void QuickSort(int* array, int startIndex, int endIndex, int &counter) {
    int pivot = array[startIndex];                  //pivot element is the leftmost element
    int splitPoint;

    if (endIndex > startIndex)                                                                                      
    {
        // counter++; // Don't count here
        splitPoint=SplitArray(array, pivot, startIndex, endIndex, counter);
        array[splitPoint] = pivot;
        QuickSort(array, startIndex, splitPoint - 1, counter);   //Quick sort first half
        QuickSort(array, splitPoint + 1, endIndex, counter);     //Quick sort second half
    }
}

互换没有变化:

void swap(int &a, int &b) {
    int temp;
    temp = a;
    a = b;
    b = temp;
}

SplitArray进行比较,因此计数器应在此处递增:

 int SplitArray(int* array,int pivot,int startIndex,int endIndex,int &counter) {
        int leftBoundary = startIndex;
        int rightBoundary = endIndex;

    while ((++counter) && (leftBoundary < rightBoundary))              
    {
        while (pivot < array[rightBoundary]       
            && rightBoundary > leftBoundary)     
        {
            rightBoundary--;                        
        }
        swap(array[leftBoundary], array[rightBoundary]);


        while ((++counter) && (pivot >= array[leftBoundary])     
            && leftBoundary < rightBoundary)      
        {
            leftBoundary++;                      
        }
        swap(array[rightBoundary], array[leftBoundary]);            
    }
    return leftBoundary;                              

}