数组移动算法算法实现

    对于有n个元素的数组 int a[n]={....};写一个高效算法将数组内容循环左移m位
比如: int a[6] ={1,2,3,4,5,6} ,循环左移3位得到结果{456123},
要求:
1不允许另外申请数组空间,但可以申请少许变量
2不允许采用每次左移

//////////////////////////////////////////////
算法的基本思想如下:
设有一个包含8个数的数组 int a[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 将其内容循环左移3位,即左移后的
结果是4, 5, 6, 7, 8, 1, 2, 3。
    从上例可以看出,将1,2,3移到了数组的最后,从4开始,直到8都往前移动了3个位置。因此我们可设想
将1,2,3看成一个整体先和4, 5, 6交换, 再和7, 8交换。
    第一次交换的结果:
    4, 5, 6, 1, 2, 3, 7, 8
    由于7,8只有两位,因此第二次交换只和1,2,3中的1,2进行交换。结果如下:
    4, 5, 6, 7, 8, 3, 1, 2。
    可以看出,前五位已经满足了最终结果,只有后3位还不满足最终结果。但是只要将3, 1, 2看成一个
子数组,再将这个子数组循环左移1位,即可变成1, 2, 3。

    因此在移动元素时可将要左移的m位看成一个整体(如上例中的1, 2, 3),依次和它后面的相同位数的
数组元素交换,如果后面的元素不足m位,假设为t位,t < m,那么只交换t位,这样,前面的数组元素(前n - m个元素一定满足条件)。
最后将后面m个元素看成一个子数组,再对其进行循环左移m - n % m位。

算法的时间复杂度为O(n),空间复杂度为O(1)。

c实现如下(move_array为算法实现函数,并带有测试用例):

#include <stdio.h>
void swap(int *a, int *b)
{
    
int x;
    x 
= *a;
    
*= *b;
    
*= x;
}
//这个函数为算法实现部分
/////////////////////////////////////////
void move_array(int data[], int n, int m)
{
    
int i, j;
    m 
= m % n;
    
if(m == 0return;
    
for(i = 0; i < n - m; i += m)
    {
        
for(j = i; j < i + m && j < n - m; j++)
        {
            swap(
&data[j], &data[j + m]);
        }
    }
    move_array(data 
+ n - m, m, m - n % m);
}
/////////////////////////////////////////
int main()
{
    
int data1[] = {12345678};
    
int data2[] = {1234567891011121314};
    
int data3[] = {123456789};
    
int data4[] = {123456};
    
int data5[] = {123456789101112131415161718};
    
int i;
    move_array(data1, 
85);
    
for(i = 0; i < 8; i++)
        printf(
"%d ", data1[i]);
    printf(
"\n");

    move_array(data2, 
1418);
    
for(i = 0; i < 14; i++)
        printf(
"%d ", data2[i]);
    printf(
"\n");

    move_array(data3, 
93);
    
for(i = 0; i < 9; i++)
        printf(
"%d ", data3[i]);
    printf(
"\n");

    move_array(data4, 
63);
    
for(i = 0; i < 6; i++)
        printf(
"%d ", data4[i]);
    printf(
"\n");

    move_array(data5, 
1817);
    
for(i = 0; i < 18; i++)
        printf(
"%d ", data5[i]);
    printf(
"\n");

    
return 0;
}

posted on 2008-05-16 19:37  银河使者  阅读(1880)  评论(1编辑  收藏  举报

导航