#include<stdio.h>
#include<assert.h>
void Left_Move_Array(int* a, int size)//数组向左移一位
{
assert(a != nullptr && size > 0);//数组检查,结果为真向下执行
int temp = a[0];//保存首元素
for (int i = 0; i < size - 1; ++i)//左移size - 1 次
{
a[i] = a[i + 1];
}
a[size - 1] = temp;//首元素置于数组末尾
return;
}
void Right_Move_Array(int *a, int size)//数组向右移一位
{
assert(a != nullptr && size > 0);//数组检查
int temp = a[size - 1];//保存数组最后一个元素
for (int i = size - 1; i > 0; --i)//执行size - 1 次,各元素右移一位
{
a[i] = a[i - 1];
}
a[0] = temp;//末尾元素置于数组首位
return;
}
void Left_Move_Array_Key(int* a, int size, int k)//左移k位
{
assert(a != nullptr && size > 0);//检查
k = k % size;//提高效率,若数组规模为10,那么移动4次和移动14次是一样的
if (k >= 0)
{
while (k--)//左移k位相当于一次移动一位,移动k次
{
Left_Move_Array(a, size);
}
}
else
{
while (k++)//若输入的值是负值,左移相当于右移
{
Right_Move_Array(a, size);
}
}
return;
}
void Right_Move_Array_Key(int* a, int size, int k)//右移k位
{
assert(a != nullptr && size > 0);//检查
Left_Move_Array_Key(a, size, -k);//刚好与左移k位相反
return;
}
int main()
{
const int n = 10;
int ar[n] = { 1,2,3,4,5,6,7,8,9,10 };
Right_Move_Array_Key(ar, n, 3);
for (int j = 0; j < n; ++j)
{
printf("%d\n", ar[j]);
}
return 0;
}
上述代码时间复杂度较大,下面我们来看一种复杂度较小的解法,以左移为例。假如要讲一个数组左移k位,我们可以将数组从下标k处分开,将0到k-1下标分为一组,将k到n-1分为一组,然后将每个数组最左边元素(设为left)和最右边元素(设为right)交换,然后left++且right- - ,直至left = right时为止,然后再将整个数组的两端元素两两交换即可完成。
例如一个数组ar = {1,2,3,4,5,6,7,8,9,10},要左移4位,我们可以把下标为0~3的元素,即1 2 3 4 分为一组,剩下的元素分为一组,然后两两交换使其原地逆置,即变为{4,3,2,1,10,9,8,7,6,5},再将整个数组两两交换即变为{5,6,7,8,9,10,1,2,3,4},左移完成,这样的解法可以将时间复杂度降至O(k)。
代码如下:
#include<stdio.h>
#include<assert.h>
void swap(int* a, int* b)//交换函数
{
int temp = *a;
*a = *b;
*b = temp;
return;
}
void Resreve(int* br, int left, int right)//数组就地逆置函数
{
assert(br != nullptr && left < right);//数组检查
while (left < right)//当left < right 时 将 left和right交换反复执行
{
swap(&br[left], &br[right]);
left++;
right--;
}
return;
}
void Left_Move_Key(int* br, int k, int n)//左移函数
{
assert(br != nullptr && n > 0);//数组检查
Resreve(br, 0, k - 1);//就地逆置前k-1个元素
Resreve(br, k, n - 1);//就地逆置后n - k 个元素
Resreve(br, 0, n - 1);//在整个数组中将两端元素两两交换完成左移任务
}
int main()
{
const int n = 10;
int ar[n] = { 1,2,3,4,5,6,7,8,9,10 };
Left_Move_Key(ar, 4, n);
for (int i = 0; i < n; ++i)
{
printf("%4d", ar[i]);
}
return 0;
}