微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++ 计数快速排序比较 <未解决>

如何解决C++ 计数快速排序比较 <未解决>

我正在从事一个项目,该项目要求我们实现不同的排序并添加计数器变量以测量具有不同数组大小的运行时。

我的问题是输出与预期输出不一样

我已经完成了插入排序并正确计算了比较次数

我可以使用引用参数

感谢任何反馈。

输出:[从答案更新]

Quick sort           16          384         6401        74378

预期输出


Array Size:          10         100         1000         10000
--------------------------------------------------------------------
Quick Sort           35         630         10292        132882 

数组大小为 10 的数组内容是什么:

内容与使用的种子保持一致。

Insertion sort

[ 935,942,697,299,382,579,408,181,366,505 ] //unsorted
[ 181,505,935,942 ] //sorted

程序:[从答案更新]

#include <iostream>
#include <stdlib.h>
#include <iomanip>
#include <cmath>
      /******************************/
      /* Start of Quick Sort Algorithm */
      /******************************/



static const int MIN_SIZE  = 10; // Smallest size of an array that quicksort will sort

/**
 * Sorts the items in an array into ascending order.
 */
template<class ItemType>
int insertionSort(ItemType theArray[],int first,int last) {
  int count = 0;
    for (int unsorted = first + 1; unsorted <= last; unsorted++) {
        ItemType nextItem = theArray[unsorted];
        int loc = unsorted;
        while ((loc > first) && (count++,theArray[loc - 1] > nextItem)) {
            theArray[loc] = theArray[loc - 1];
            loc--;
        }
        theArray[loc] = nextItem;
    }
    return count;
}

/**
 * Arranges two specified array entries into sorted order by
 * exchanging them,if necessary.
 * */
template<class ItemType>
void order(ItemType theArray[],int i,int j) {
    if (theArray[i] > theArray[j]) {
        std::swap(theArray[i],theArray[j]);
    }
}

/**
 * Arranges the first,middle,and last entry in an array in sorted order.
 */
template<class ItemType>
int sortFirstMiddleLast(ItemType theArray[],int last) {
    int mid = first + (last - first) / 2;
    order(theArray,first,mid); // Make theArray[first] <= theArray[mid]
    order(theArray,mid,last);  // Make theArray[mid] <= theArray[last]
    order(theArray,mid); // Make theArray[first] <= theArray[mid]

    return mid;
}

/**
 * Partitions the entries in an array about a pivot entry for quicksort.
 */
template<class ItemType>
int partition(ItemType theArray[],int last,int &counter) {
    // Choose pivot using median-of-three selection
    int pivotIndex = sortFirstMiddleLast(theArray,last);

    // Reposition pivot so it is last in the array
    std::swap(theArray[pivotIndex],theArray[last - 1]);
    pivotIndex = last - 1;
    ItemType pivot = theArray[pivotIndex];

    // Determine the regions S1 and S2
    int indexFromLeft = first + 1;
    int indexFromright = last - 2;

    bool done = false;
    while (!done) {
        // Locate first entry on left that is >= pivot
        while (theArray[indexFromLeft] < pivot) {
          counter++;//I incremented Count here
          indexFromLeft = indexFromLeft + 1;
        }

        // Locate first entry on right that is <= pivot
        while (theArray[indexFromright] > pivot) {
          counter++;
          indexFromright = indexFromright - 1;
        }

        if (indexFromLeft < indexFromright) {
            std::swap(theArray[indexFromLeft],theArray[indexFromright]);
            indexFromLeft = indexFromLeft + 1;
            indexFromright = indexFromright - 1;
        }
        else {
            done = true;
        }
    }

    // Place pivot in proper position between S1 and S2,and mark its new location
    std::swap(theArray[pivotIndex],theArray[indexFromLeft]);
    pivotIndex = indexFromLeft;

    return pivotIndex;
}

/**
 * Sorts an array into ascending order. Uses the quick sort with
 * median-of-three pivot selection for arrays of at least MIN_SIZE
 * entries,and uses the insertion sort for other arrays.
 */
template<class ItemType>
int quicksort(ItemType theArray[],int last) {
    int result = 0;
    int counter = 0;
    if (last - first + 1 < MIN_SIZE) {
        result = insertionSort(theArray,last);
    }
    else {
        // Create the partition: S1 | Pivot | S2
        int pivotIndex = partition(theArray,last,counter);
        // Sort subarrays S1 and S2
         result += quicksort(theArray,pivotIndex - 1);
         result += quicksort(theArray,pivotIndex + 1,last);
         result += counter;
    }
    return result; //return final count
}


      /******************************/
      /* Start of Sorting Benchmark  */
      /******************************/
int* makeRandomArray(int n,int seed) {
    srand(seed);
    int * a = new int[n];
    for (int i = 0; i < n; i++) {
        a[i] = rand() % 1000;
    }
    return a;
}

int main(){
    const int seed = 9000;
    int *a;

    /******************************/
    /* Start of Quick Sort    */
    /******************************/
    std::cout << "Quick sort";

    int n = 10;
    a = makeRandomArray(10,seed);
    std::cout <<std::setw(13)<< quicksort(a,n-1);
    delete[] a;

    n = 100;
    a = makeRandomArray(100,n-1);
    delete[] a;

    n = 1000;
    a = makeRandomArray(1000,n-1);
    delete[] a;

    n = 10000;
    a = makeRandomArray(10000,n-1)<<std::endl;
    delete[] a;

    return 0;
}

解决方法

在快速排序中,当分区方法/函数正在寻找违反规则的元素时进行比较,即小于主元的元素必须在主元的左侧,大于它的元素必须在右侧。这两个 while 正是这样做的。第一个继续向右移动,而当前元素小于枢轴(第一组比较)。第二个 while 做相反的操作,即,当当前元素大于主元时,它继续向左移动,进行第二组比较。如果左侧索引小于右侧索引,则表示它找到了一个大于左侧枢轴的元素和一个小于右侧枢轴的元素,因此它将交换它们。这个过程继续,直到左边的索引通过右边的索引。当它完成时,所有左边的值都小于枢轴,所有的右边值都大于枢轴,因此它将枢轴与较小侧的最后一个元素交换并返回枢轴位置,因为现在,枢轴在找到了该分区的正确位置和“中间”,允许排序过程继续到左侧分区和右侧分区。

while (theArray[indexFromLeft] < pivot) {
    // count here
    indexFromLeft = indexFromLeft + 1;
}

while (theArray[indexFromRight] > pivot) {
    // and here
    indexFromRight = indexFromRight - 1;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。