百度知道上,遇到一个提问:
对1 2 3 4 5 6 7 8 9 10进行重新排列,输出8 9 10 1 2 3 4 5 6 7。
原解法写成了n*m次移动
for(j=1;j<=3;j++) { k=a[9]; for(i=9;i>0;i--) a[i]=a[i-1]; a[0]=k; }
分析:n个数中移动m个的,应该只需要n+m个空间移动n+m次或0空间交换n次。。
如果有13个空间,可以直接向后移动三个元素再重新插入,次数等于n+m次。
#define N 10 #define M 3 for (int i = 0; i < N - M; ++i) a[N + M - 1 + i] = a[N - 1 - i]; for (int i = 0; i < M; ++i) a[M - 1 - i] = a[N + M - 1 + i];
如果没有空间,通过整体交换,只交换3+3+4次,相当于int(n / m) * m + int(m / (n mod m))*(n mod m)次等于n次。
//把q位上的n个数移动到p位上。 void swapall(int a[], int p, int q, int n) { for (int i = 0; i < n; i ++) { int x = a[q + i]; a[q + i] = a[p + i]; a[p + i] = a[q + i]; } } /* p < q, n > 1 */ void move(int a[], int p, int q, int n) { while ( p + n < q) { swapall(a, p, q, n); p = p + n; } while ( q - p < n) { int m = q - p; swapall (a, p, q, m); n = n - m; p = q; q = p + m; } }