题目
设将n (n>1)个整数存放到一维数组R中,设计一个在时间和空间两方面尽可能高效的算法。将R中保存的序列循环左移p (0<p<n)个位置,即将R中的数据由(x0,x1,x2,…,xn-1)变换为(xp,xp+1,…,xn+1,x0,x1,…,xp-1),要求:
- 给出算法的基本设计思想。
- 根据设计思想,用C/C++实现算法,关键处给出注释。
- 说明算法的时间复杂度和空间复杂度。
基本设计思想
- 由上述要求,分析出题目主要要求实现数组R中元素循环左移p位,返回实现后数组。
- 因此,第一步我们可以先考虑将数组R内所有元素逆置,得到数组(xn-1,xn-2,…,x2,x1,x0)。
- 接下来,将数组R中前n-p个元素逆置,得到数组(xp,xp+1,…,xn-1,xp-1,xp-2,…x2,x1,x0)。
- 然后,再逆置数组R中后p个元素,得到题目要求数组(xp,xp+1,…,xn-1,x0,x1,…,xp-1)。
代码实现
Array LinearList::Reverse(int left,int right)//传入顺序表arr逆置的左右临界
{
if(arr.length <= 1)
return arr;
int i = left,j = right-1;//设置哨兵i,j分别指向左右临界的下标
int temp = 0;
while(i < j) //交换哨兵指向的元素位置
{
temp = arr.data[i];
arr.data[i++] = arr.data[j];
arr.data[j--] = temp;
temp = 0;
}
return arr;
}
Array LinearList::Question_10(int p)
{
if(arr.length <=1)//判断非法数组长度
return arr;
cout<<"Move "<<p<<" bit left"<<endl;
Reverse(0,arr.length); //逆置数组R中的全部元素
Reverse(0,arr.length-p); //逆置数组R中前n-p个元素
Reverse(arr.length-p,arr.length); //逆置数组R中后p个元素
return arr;
}