问题:把一个含有N个元素的数组循环右移K位。
例:数组为123456,循环右移3位后为:456123。
分析:问题为数组循环移位,在实现时如果按数组元素一个一个的移动,时间复杂度O(n*k)。将移位前后的数组对比可以看出,数组循环右移K位相当于将数组最后K个元素与前n-k个元素整体对调位置。在例子中,就相当于456与123对调位置。因此我们的算法思想为:将数组分为前n-k个元素和后k个元素组成的两个数组。将两个子数组分别转置,再将整个数组转置,最后的结果就是数组最后K个元素与前n-k个元素整体对调位置。注:思想来源于《编程珠玑》2.3节。
代码:
- #include<stdio.h>
- #include<assert.h>
- /*print all value in array orderly*/
- void print_array(int array[],int n)
- {
- int i;
- for(i=0;i<n;++i)
- printf("%d ",array[i]);
- printf("/n");
- }
- /*reverse subsequence(between b and e) in array */
- void reverse(int array[],int b,int e)
- {
- assert((b>=0)&&(e>=0)&&(b<e));
- int i;
- int end = (e-b+1)/2;
- int tmp;
- for(i=0;i<end;++i)
- {
- tmp = array[b+i];
- array[b+i]=array[e-i];
- array[e-i]=tmp;
- }
- }
- /*shift sfn values at the end of array*/
- void array_shift(int array[],int n,int sfn)
- {
- reverse(array,0,n-1-sfn);
- reverse(array,n-sfn,n-1);
- reverse(array,0,n-1);
- }
- int main(int argc,char * argv[])
- {
- int array[10]={1,2,3,4,5,6,7,8,9,10};
- array_shift(array,10,5);
- print_array(array,10);
- return 0;
- }