统计逆序数个数

  用借助于归并排序每次对分组的排序可以避免以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 }

 

 

posted @ 2012-09-23 16:12  answer0107  阅读(199)  评论(0)    收藏  举报