逆序数对

来源:互联网 发布:外汇交易相关经济数据 编辑:程序博客网 时间:2024/04/28 15:45

在一个数组中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序数对。给定一数组,统计数组中的逆序数对。


比较经典的题目,用来练习一下归并排序。写了两个算法,都是O(nlgn),不过算法2效率应该会稍微高一些, 因为少了lgn次的数组复制,不过写起来容易出错。


void MergeSort::test() {int a[] = {2, 1, -6, 3, -2, 8, 3, 9, 7, 6};//int a[] = {8, 1, 2, -2};cout << "Before sort the array is: ";print(a, sizeof(a)/sizeof(int));sort(a, sizeof(a)/sizeof(int));cout << "After sort the array is: ";print(a, sizeof(a)/sizeof(int));cout << endl;}void MergeSort::sort(int *data, int n) {int *tmp = new int[n];for (int i = 0; i < n; ++i) {tmp[i] = data[i];}int count = mergeSort1(data, 0, n - 1, tmp);// int count = mergeSort2(tmp, 0, n - 1, data);cout << "The count of inverse pairs is: " << count << endl;delete []tmp;}int MergeSort::mergeSort1(int *data, int left, int right, int *tmp) {int count = 0;if (left < right) {int mid = left + (right - left) / 2;count += mergeSort1(data, left, mid, tmp);count += mergeSort1(data, mid + 1, right, tmp);int i = left;int j = mid + 1;int k = left;while (i <= mid && j <= right) {if (data[i] <= data[j]) {tmp[k++] = data[i++];}else {tmp[k++] = data[j++];count += mid - i + 1;}}while (i <= mid) {tmp[k++] = data[i++];}while (j <= right) {tmp[k++] = data[j++];}for (i = left; i <= right; ++i) {data[i] = tmp[i];}}return count;}int MergeSort::mergeSort2(int *data, int left, int right, int *tmp) {int count = 0;if (left < right) {int mid = left + (right - left) / 2;count += mergeSort2(tmp, left, mid, data);count += mergeSort2(tmp, mid + 1, right, data);int i = left;int j = mid + 1;int k = left;while (i <= mid && j <= right) {if (data[i] <= data[j]) {tmp[k++] = data[i++];}else {tmp[k++] = data[j++];count += mid - i + 1;}}while (i <= mid) {tmp[k++] = data[i++];}while (j <= right) {tmp[k++] = data[j++];}}return count;}


0 0
原创粉丝点击