具有偶数和奇数分开的数组的函数的复杂性

问题描述

所以我有一个数组,其中有偶数和奇数。 我必须先用奇数排序,然后再用偶数排序。 这是我的处理方法

 int key,val;
int odd = 0;
int index = 0;

for(int i=0;i<max;i++)
{
    if(arr[i]%2!=0)
    {
        int temp = arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
        index++;
        odd++;
    }
}

首先,我将偶数和奇数分开,然后对其进行排序。 对于排序,我有以下代码

for (int i=1; i<max;i++)
{
    key=arr[i];
    
    if(i<odd)
    {
       val = 0;
    }
    if(i>=odd)
    {
        val = odd;
    }
    
    for(int j=i; j>val && key < arr[j-1]; j--)
    {
        arr[j] = arr[j-1];
        arr[j-1] = key;
    }
}

我面临的问题是我找不到上述排序代码的复杂性。 像插入排序一样适用于第一个奇数。 完成后,我将跳过该部分并开始对偶数进行排序。 如果我对数组进行了排序,这是我的排序方法,例如: 3 5 7 9 2 6 10 12 complexity table

这一切如何运作? 在第一个for循环中,我遍历循环并将所有奇数放在偶数之前。 但是由于它没有对它们进行排序。 在具有插入排序的下一个for循环中。我基本上所做的只是像使用if语句在数组中首先仅对奇数排序一样。然后,当i ==奇数时,嵌套的for循环便不会遍历所有奇数,而是仅对偶数进行计数,然后对其进行排序。

解决方法

我假设您知道分区(假设为A)和排序算法(我们称其为B)的复杂性。

您首先对n元素数组进行分区,然后对m元素进行排序,最后对n - m元素进行排序。因此总复杂度为:

A(n) + B(m) + B(n - m)

根据实际的AB,您可能应该能够进一步简化它。

编辑:顺便说一句,除非您的代码目标不是尝试实施分区/排序算法,否则我认为这要清楚得多:

#include <algorithm>
#include <iterator>

template <class T>
void partition_and_sort (T & values) {
  auto isOdd = [](auto const & e) { return e % 2 == 1; };
  auto middle = std::partition(std::begin(values),std::end(values),isOdd);
  std::sort(std::begin(values),middle);
  std::sort(middle,std::end(values));
}

在这种情况下,复杂度为O(n) + 2 * O(n * log(n)) = O(n * log(n))

编辑2:我错误地假设std::partition保留元素的相对顺序。事实并非如此。修复了代码示例。