c++ - 归并排序中反转的反转计数值

标签 c++ c count mergesort inversion

下面是计算数组中反转的代码。我对此部分有疑问:

     inv_count  = _mergeSort(arr, temp, left, mid);--i

    inv_count += _mergeSort(arr, temp, mid+1, right);--ii

     inv_count += merge(arr, temp, left, mid+1, right);--iii

在反转计数中,总反转将等于 i+ii +iii ,但我无法理解“i 和 ii 的 inv_count 甚至得到一个值,它们被递归调用并填充到函数堆栈中,但是如何”值没有传递给 inv_count 对于 i 和 ii,尽管在 iii 中,inv_count 使用 invcount=inv_count+mid-i 获取值;

   int mergeSort(int arr[], int array_size)
{
    int *temp = (int *)malloc(sizeof(int)*array_size);
    return _mergeSort(arr, temp, 0, array_size - 1);
}

/* An auxiliary recursive function that sorts the input array and
  returns the number of inversions in the array. */
int _mergeSort(int arr[], int temp[], int left, int right)
{
  int mid, inv_count = 0;
  if (right > left)
  {
    /* Divide the array into two parts and call _mergeSortAndCountInv()
       for each of the parts */
    mid = (right + left)/2;

    /* Inversion count will be sum of inversions in left-part, right-part
      and number of inversions in merging */
    inv_count  = _mergeSort(arr, temp, left, mid);

    inv_count += _mergeSort(arr, temp, mid+1, right);

    /*Merge the two parts*/
    inv_count += merge(arr, temp, left, mid+1, right);
  }
  return inv_count;
}

/* This funt merges two sorted arrays and returns inversion count in
   the arrays.*/
int merge(int arr[], int temp[], int left, int mid, int right)
{
  int i, j, k;
  int inv_count = 0;

  i = left; /* i is index for left subarray*/
  j = mid;  /* i is index for right subarray*/
  k = left; /* i is index for resultant merged subarray*/
  while ((i <= mid - 1) && (j <= right))
  {
    if (arr[i] <= arr[j])
    {
      temp[k++] = arr[i++];
    }
    else
    {
      temp[k++] = arr[j++];

     /*this is tricky -- see above explanation/diagram for merge()*/
      inv_count = inv_count + (mid - i);
    }
  }

  /* Copy the remaining elements of left subarray
   (if there are any) to temp*/
  while (i <= mid - 1)
    temp[k++] = arr[i++];

  /* Copy the remaining elements of right subarray
   (if there are any) to temp*/
  while (j <= right)
    temp[k++] = arr[j++];

  /*Copy back the merged elements to original array*/
  for (i=left; i <= right; i++)
    arr[i] = temp[i];

  return inv_count;
}

最佳答案

这是反转计数的工作代码。--i --ii --iii 与反转计数无关。

合并排序时的逆序总数等于左排序和右排序以及左右合并得到的逆序之和。如果你对代码不清楚,请评论。

#include <iostream>
#include <stdio.h>
#include <limits.h>
#include <algorithm>
using namespace std;
const int size = 1000000;
long long int array[size];
long long int merge(long long int a[], long long int beg, long long int mid,
    long long int end) {
    long long int inverse = 0;
    long long int lsize = (mid - beg) + 1;
    long long int rsize = (end - mid);
    long long int left[lsize + 1];
    long long int right[rsize + 1];
    long long int i;
    long long int j = beg;
    for (i = 0; i < lsize; ++i, ++j) {
        left[i] = a[j];
    }
    j = mid + 1;
    for (i = 0; i < rsize; ++i, ++j) {
        right[i] = a[j];
    }
    left[lsize] = LONG_LONG_MAX;
    right[rsize] = LONG_LONG_MAX;
    j = 0;
    i = 0;
    for (int k = beg; k <= end; ++k) {
       if (left[i] <= right[j]) {
            a[k] = left[i];
            ++i;
       } else {
            a[k] = right[j];
            inverse += (lsize - i);
            ++j;
      }
    }
   return inverse;
}

long long int merge_sort(long long int iArray[], long long int beg,
        long long int end) {
     if (beg < end) {
        long long int mid;
        long long int left = 0;
        long long int right = 0;
        long long int total = 0;
        mid = (beg + end) / 2;
        left = merge_sort(iArray, beg, mid);
        right = merge_sort(iArray, mid + 1, end);
        total = merge(iArray, beg, mid, end);
        return left + right + total;
     } else {
         return 0;
     }
}

关于c++ - 归并排序中反转的反转计数值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22740881/

相关文章:

c++ - 关于 C++ 运算符的基本问题?

c++ - 在 C++/G++ 中是否有*任何*方法来获取 C 样式数组的长度?

c++ - keybd_event 表现出奇怪的行为

c++ - OpenMP:并行不做任何事情

c - 使用 fputc 和 fgetc 写入文件最终只有 0

php - 将列添加到一个表中,该表是另一个表的 COUNT

sql - 具有不同代码的重复记录。选择没有 'useful' 且至少有一个 'not found' 的代码

c - 定义一个结构,其中一个成员指向另一个成员

c - 您好,我正在使用 JDoodle 练习 C 编程,我创建了一个指向 .text 文件的 fpointer,如何打开这个 .text 文件并查看数据?

javascript - 计算元素在数组中出现的次数