设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同。 如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数。 例如,数组(3,1,4,5,2)的逆序对有(3,1),(3,2),(4,2),(5,2),共4个。
具体代码:
void reverse_num(int a[],int s ,int t) //直接蛮力递归法,T=O(n平方); { if (s == t) { return; } else { reverse_num(a, s+1, t); for (int i=s+1; i <= t; i++) { if (a[s] >a[i]) cout << "<" << a[s] <<","<< a[i] << ">" << " "; } return; } }具体代码
void disp(int a[], int s,int mid,int temp)//输出关于a[j]与子序列a[i...mid]构成的逆序对 { for (int i = s; i <=mid; i++) { cout << "<" << a[i] << "," << temp << ">" << " "; } } void merge(int a[], int low, int mid, int high) //将a[low..mid]和a[mid+1..high]两个相邻的有序子序列归并成一个有序子序列a[low..high] { int i = low, j = mid + 1, k = 0; int* tampa; tampa = (int*)malloc((high - low + 1) * sizeof(int));//临时存放数组 while (i <= mid && j <= high)//扫描1表和2表 { if (a[i] <= a[j]) { tampa[k] = a[i]; i++; k++; } else { tampa[k] = a[j]; disp(a, i, mid, a[j]);//将此时关于a[j]对应的左半子序列中的逆序数打印 j++; k++; } } while (i <= mid)//将1表剩下的放进去 { tampa[k] = a[i]; i++; k++; } while (j <= high)//将2表剩下的放进去 { tampa[k] = a[j]; j++; k++; } for (k = 0, i = low; i <= high; i++, k++)//将tampa复制回a中 { a[i] = tampa[k]; } free(tampa); } void mergePass(int a[], int length, int n)//一趟二路归并排序 { int i; for (i = 0; i + 2 * length - 1 < n; i = i + 2 * length) { merge(a, i, i + length - 1, i + 2 * length - 1); } if (i + length - 1 < n)//若余下两个子表,后者长度小于length { merge(a, i, i + length - 1, n - 1);//归并这两个表 } } void merge_sort(int a[], int n)//二路归并算法 { int length; for (length = 1; length < n; length = 2 * length) { mergePass(a, length, n); } } int main() { int a[] = { 3,1,4,5,2 }; merge_sort(a, 5); return 0; }