关于算法导论上一道题的思考,求逆序对数目

本文探讨了逆序对的概念及其与插入排序运行时间的关系,并提供了一种使用归并排序算法在θ(n log n)最坏情况下确定任何排列中逆序对数量的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目是第二章的一个思考题:

Problems 2-4: Inversions Let A[1 ‥ n] be an array of n distinct numbers. If i < j and A[i] > A[j], then the pair (i, j) is called an inversion of A. List the five inversions of the array 〈2, 3, 8, 6, 1〉. What array with elements from the set {1, 2, . . . , n} has the most inversions? How many does it have? What is the relationship between the running time of insertion sort and the number of inversions in the input array? Justify your answer. Give an algorithm that determines the number of inversions in any permutation on n elements in Θ(n lg n) worst-case time. (Hint: Modify merge sort.)

求逆序对数目,这里给出第四个问题的解法,使用归并排序来实现,归并排序的代码是我在网上找到的,我只是在里面添加了一些代码。依附于归并排序的算法的复杂度,这个求逆序的时间复杂度的最好最坏和平均复杂度和归并的一致。如下:

#include <stdio.h> #include <stdlib.h> int all_count = 0; void merge(int data[], int p, int q, int r) { int i = 0; int j = 0; int k = 0; int n1 = 0; int n2 = 0; int low_count = 0; int move_count = 0; int *L = NULL; int *R = NULL; n1 = q - p + 1; n2 = r - q; L = (int *)malloc(sizeof(int) * n1); R = (int *)malloc(sizeof(int) * n2); for(i = 0, k = p; i < n1; i++, k++) L[i] = data[k]; for(i = 0, k = q + 1; i < n2; i++, k++) R[i] = data[k]; for(k = p, i = 0, j = 0; i < n1 && j < n2; k++) { if(L[i] < R[j]) { data[k] = L[i]; move_count += low_count; i++; } else { data[k] = R[j]; low_count++; j++; } } if(i < n1) /*all the left is in the left list greater than the right*/ { for(j = i; j < n1; j++, k++) { data[k] = L[j]; move_count += low_count; } } if(j < n2) { for(i = j; i < n2; i++, k++) data[k] = R[i]; } all_count += move_count; free(L); free(R); } void merge_sort(int data[], int p, int r) { if(p < r) { int q = (p + r) / 2; merge_sort(data, p, q); merge_sort(data, q + 1, r); merge(data, p, q, r); } } void test_merge_sort() { int data[] = {7, 1, 9, 10, 2, 3, 4}; printf("The count of the reverse is %d\n", all_count); merge_sort(data, 0, sizeof(data)/sizeof(data[0]) - 1); printf("The count of the reverse is %d\n", all_count); } int main() { test_merge_sort(); return 0; }

具体的实现其实问题已经描述的很清楚了。不多说了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值