P18.10
n个整数存放到一位数组R中,将R中的元素循环左移p个位置。
(1)算法的基本设计思想
创建另外一个数组_R,将排序后的元素放在_R中,然后利用_R更新R。
时空复杂度都贼鸡儿丢人。
(2)代码如下
#include <stdio.h>
void main()
{
int R[10];
int count;
int p;
scanf("%d", &p);
for (count = 0; count <= 9; count++)
{
R[count] = count;
}
int _R[10];
for (count = 0; count <= 9; count++)
{
if (count - p < 0)
_R[count + 10 - p] = R[count]; //注意数组元素顺序与下标的关系,我多加了一个一导致溢出
else
_R[count - p] = R[count];
}
for (count = 0; count <= 9; count++)
{
R[count] = _R[count];
printf("%d ", R[count]);
}
}
(3)复杂度
时间复杂度O(n)
空间复杂度O(n)
(4)改进
设置_R的大小为p而不是n,仅保存前p个元素,然后第p个之后的元素往前移,再把_R中的元素放在R之后。
时间复杂度O(n)
空间复杂度O(p)
较好的算法
(1)算法的基本设计思想
设数组元素逆置函数Reverse(*R,a,b),R为想要逆置的数组名称,a为要逆置的第一个元素,b为要逆置的最后一个元素。
本质上是把R分为两个数组A和B,然后把AB变为BA。
算法为先分别逆置A和B,得到A'和B',然后将逆置后的数组A'B'整体再逆置。
效果如下:
以0123456789,p=5为例:
R=0123456789
A=01234
B=56789
A'=43210
B'=98765
A'B'=4321098765
R'=5678901234
(2)代码如下
#include <stdio.h>
void Reserve(int *R, int Rstart, int Rend);
void main()
{
int R[10];
int count;
int p;
scanf("%d", &p);
for (count = 0; count <= 9; count++)
{
R[count] = count;
}
Reserve(R,0,p-1);
Reserve(R, p, 9);
Reserve(R, 0, 9);
for (count = 0; count <= 9; count++)
{
printf("%d ", R[count]);
}
}
void Reserve(int *R, int Rstart, int Rend)//注意数组作为参数传入时的方式
{
int a;
for (; Rstart <= Rend; Rend--, Rstart++)
{
a = R[Rend];
R[Rend] = R[Rstart];
R[Rstart] = a;
}
}
(3)复杂度
时间复杂度O(n)
空间复杂度O(1)