c++ - 计算合并排序算法的交换/比较次数

标签 c++ algorithm sorting merge

我需要计算在合并排序期间发生了多少次交换和比较,我认为我的比较数计数很好,只是由于递归我得到的数字与我的数组长度一样多,不知何故我需要将这些数字存储到合并中的变量排序功能?也很想知道如何计算总掉期的想法

    void merge(double arr[], int l, int m, int r)
    {
        int counter = 0;//number of comparisons
        int i, j, k;
        int n1 = m - l + 1;
        int n2 =  r - m;
        int cc;
        /* create temp arrays */
        double L[n1], R[n2];
        /* Copy data to temp arrays L[] and R[] */
        for (i = 0; i < n1; i++)
            L[i] = arr[l + i];
        for (j = 0; j < n2; j++)
            R[j] = arr[m + 1+ j];
        /* Merge the temp arrays back into arr[l..r]*/
        i = 0; // Initial index of first subarray
        j = 0; // Initial index of second subarray
        k = l; // Initial index of merged subarray
        while (i < n1 && j < n2)
            {

                if (L[i] <= R[j])
                {
                    arr[k] = L[i];
                    i++;
                }
                else
                {
                    arr[k] = R[j];
                    j++;
                }
                k++;
                counter++;
        }
        cout << counter << endl;
    /* Copy the remaining elements of L[], if there
       are any */
        while (i < n1)
        {
            arr[k] = L[i];
            i++;
            k++;
        }
    /* Copy the remaining elements of R[], if there
       are any */
        while (j < n2)
        {
            arr[k] = R[j];
            j++;
            k++;
              }
    }
    void mergeSort(double arr[], int l, int r)
         {
          if (l < r)
         {
            // Same as (l+r)/2, but avoids overflow for
        // large l and h
        int m = l+(r-l)/2;
        // Sort first and second halves
        mergeSort(arr, l, m);
        mergeSort(arr, m+1, r);
        merge(arr, l, m, r);
        }
    }

最佳答案

我会以不同的方式完成这项工作。

我不会尝试对排序本身进行检测以跟踪数量或比较和交换,而是创建一个类型来跟踪比较和/或交换的次数。我懒得写一个完整的合并排序来演示它,但这是一个冒泡排序:

#include <algorithm>
#include <iostream>
#include <vector>

namespace instrumented {

    template <class T>
    class wrapper {
        T value;
    public:
        static std::size_t comparisons;
        static std::size_t swaps;
        wrapper(T val) : value(val) {}
        bool operator<(wrapper const &other) { ++comparisons; return value < other.value; }
        operator T() const { return value; }

        static void reset() { comparisons = swaps = 0; }

        static std::ostream &report(std::ostream &os) {
            os << "comparisons: " << comparisons << "\n";
            os << "swaps: " << swaps << "\n";
            comparisons = 0;
            swaps = 0;
            return os;
        }
    };

    template <class T>
    std::size_t wrapper<T>::comparisons;

    template <class T>
    std::size_t wrapper<T>::swaps;

    template <class T>
    void swap(wrapper<T> &a, wrapper<T> &b) {
        ++wrapper<T>::swaps;
        auto temp{ a };
        a = b;
        b = temp;
    }
}

template <class T>
void sort(std::vector<T> &input) {
    std::vector<instrumented::wrapper<T>> values;

    for (auto const & i : input)
        values.push_back(i);

    for (auto i = 0; i < values.size() - 1; i++)
        for (auto j = i + 1; j < values.size(); j++)
            if (values[j] < values[i])
                swap(values[i], values[j]);

    values[0].report(std::cout);
}

int main() {
    std::vector<int> inputs1{ 5, 4, 3, 2, 1 };
    sort(inputs1);
    std::cout << "\n";

    std::vector<int> inputs2{ 10, 9, 7, 8, 5, 100, 2, 3, 1, 17, 6 };
    sort(inputs2);
}

请注意,有了这个,您应该能够(例如)获得 std::sortstd::partial_sort 等的结果,而不仅仅是您自己的排序功能。

关于c++ - 计算合并排序算法的交换/比较次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47850495/

相关文章:

C++ 单例/事件对象范例

c++ - C++ cout和cin缓冲区,以及一般的缓冲区

javascript - 将数组(元素组合)划分为自定义分区的所有方法

java - 从列表中获取最小和最大数字

javascript - 如何按这些数组的两个元素对数组进行排序?

python - 如何按降序对二维数组的一半进行排序(numpy)

c++ - 改 rebase 数排序基数?

c++ - 将 (0&(1|0)|1) & (0|1) 等字符串转换为对应的真值

c++ - 多向哈希表

algorithm - 矩阵乘法的并行和分布式算法