问题描述
设将n(n>1)个整数存放到一维数组 arr 中。将 arr 中保存的序列循环左移p (0<p<n)个位置,即将 arr 中的数据由(X0,X1,…, Xn-1)变换为(Xp, Χρ+1, , Xn-1, Χ0, X1,…, Xp-1)。
算法思想
假设将数组扩展其两倍长,新增加的元素是其原数组的一个拷贝,前后两个数组分别记为L1和L2。那么循环左移后,下标0 ~ p-1
的元素其新的位置应在n-p ~ n-1
处,下标为p ~ n-1
的元素与L2中n ~ 2n-p-1
对应。故对数组0 ~ n-1
内的元素只需将下标为i
的元素放到i+n-p
位置,其中p ~ n-1
范围内的元素对应位置会在L2中,所以需要对n取模。
代码
核心代码
void shiftLeft(int arr[],int n,int p){
int t,i=p-1,pre=arr[i],s=n;
while(s-->0){
i=(i+n-p)%n; //下一个将要存放的位置
t=arr[i]; //暂存取出下个位置的数
arr[i]=pre; //放入前一个数
pre=t; //将下个位置数作为下次放入的数
}
}
测试代码
#include <stdio.h>
void printArray(int arr[],int n);
void shiftLeft(int arr[],int n,int p);
int length=0;
int main(int argc, char const *argv[])
{
int R[]={1,2,3,4,5,6,7,8,9,10,11};
length=sizeof(R)/sizeof(int);
printArray(R,length);
printf("\n-----------\n");
shiftLeft(R,length,6);
return 0;
}
void printArray(int arr[],int n){
for (int i = 0; i < n; i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void shiftLeft(int arr[],int n,int p){
int t,i=p-1,pre=arr[i],s=n;
while(s-->0){
i=(i+n-p)%n;
t=arr[i];
arr[i]=pre;
pre=t;
printArray(arr,n);
}
}