逆序数对

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


比较经典的题目,用来练习一下归并排序。写了两个算法,都是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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值