统计逆序数个数
用借助于归并排序每次对分组的排序可以避免以N平方的扫描的时间复杂度,用分治的思想可以把这一过程的复杂度降为O nlgn + 常数,常数为比归并排序多出来的时间
1 #include <string.h> 2 3 extern int* buffer; 4 5 int mergreversnumber(int* intarray, int startpos, int endpos) 6 { 7 int* startp = intarray + startpos; 8 int* secondp; 9 int size = endpos - startpos + 1; 10 int frontsize; 11 int backsize; 12 int rtval = 0; 13 int lrtval = 0; 14 int rrtval = 0; 15 if (size == 1) 16 return rtval; 17 frontsize = size / 2; 18 backsize = size - frontsize; 19 secondp = startp + frontsize; 20 lrtval = mergreversnumber(intarray, startpos, startpos + frontsize - 1); 21 rrtval = mergreversnumber(intarray, startpos + frontsize, startpos + size - 1); 22 rtval = merg(intarray, startp, frontsize, secondp, backsize); 23 rtval += lrtval; 24 rtval += rrtval; 25 return rtval; 26 } 27 28 int merg(int* intarray, int* leftp, int leftsize, int* rightp, int rightsize) { 29 int* pbuffer; 30 pbuffer = buffer + (leftp - intarray); 31 int frontsize = leftsize; 32 int backsize = rightsize; 33 int* startp = leftp; 34 int* secondp = rightp; 35 int rtval = 0; 36 while (frontsize != 0 && backsize != 0) 37 { 38 if (*startp < *secondp) 39 { 40 *pbuffer = *startp; 41 startp ++; 42 frontsize --; 43 pbuffer ++; 44 } 45 else if (*startp == *secondp) 46 { 47 *pbuffer = *startp; 48 pbuffer ++; 49 frontsize --; 50 startp ++; 51 *pbuffer = *secondp; 52 pbuffer ++; 53 backsize --; 54 secondp ++; 55 } 56 else{ 57 *pbuffer = *secondp; 58 //左半数组中的值现在都要比右边第一个数大,所以要加上左半数组的大小 59 rtval += frontsize; 60 secondp ++; 61 backsize --; 62 pbuffer ++; 63 } 64 } 65 if (frontsize != 0) 66 { 67 while (frontsize != 0) 68 { 69 *pbuffer = *startp; 70 startp ++; 71 frontsize --; 72 pbuffer ++; 73 } 74 } 75 else if (backsize != 0) 76 { 77 while (backsize != 0) 78 { 79 *pbuffer = *secondp; 80 secondp ++; 81 backsize --; 82 pbuffer ++; 83 } 84 } 85 pbuffer = buffer + (leftp - intarray); 86 memcpy(intarray + (leftp - intarray), pbuffer, sizeof(int) * (leftsize + rightsize)); 87 return rtval; 88 } 89 90 91 //----------------------------------------------------------------main函数---------------------------- 92 #include <stdio.h> 93 #include <stdlib.h> 94 95 int* buffer; 96 97 void main() 98 { 99 int len, startpos, endpos; 100 int a[50]; 101 int b[50]; 102 int i; 103 int count = 0; 104 scanf("%d%d%d", &len, &startpos, &endpos); 105 for (i = 0; i != len; i++) 106 { 107 scanf("%d", &a[i]); 108 b[i] = a[i]; 109 } 110 buffer = (int*)malloc(sizeof(int) * len); 111 count = mergreversnumber(a, startpos, endpos); 112 printf("这组数中的逆序数个数为%d个\n", count); 113 114 for (i = 0; i != len; i++) 115 { 116 printf("%d ", b[i]); 117 } 118 119 printf("\n"); 120 for (i = 0; i != len; i++) 121 { 122 printf("%d ", a[i]); 123 } 124 free(buffer); 125 }

浙公网安备 33010602011771号