思想:把前p个元素保存到另一个数组,然后对A的后n-p个元素进行移动,后n-p ~ n个元素进行重新赋值。(这个是时间复杂度空间复杂度都比较高的)
//将A中的元素循环左移p个位置
int moveP(Sqlist& A, int p) {
if (A.length == 0)return 0;
Sqlist B;
B.length = p;
for (int i = 0; i < p; i++) {
B.a[i] = A.a[i];
}
for (int j = 0; j < A.length; j++) {
if (j < A.length - p) A.a[j] = A.a[j + p];
else A.a[j] = B.a[j + p-A.length];
}
}
移动1位:
移动3位:
好的思想是:将原始数组逆置,接着对0~n-p-1,n-p~n-1的元素分别再次逆置。(时间复杂度O(logn),空间复杂度O(1)).
//对数组A的某一段进行逆置
void reverse(Sqlist& A, int x, int y) {
int temp;
for (int i = 0; i <= (y-x)/2; i++) {//注意这里写成小于等于
temp = A.a[x+i];
A.a[x+i] = A.a[y - i];
A.a[y - i] = temp;
}
}
void NewmoveP(Sqlist& A, int p) {
reverse(A, 0, A.length - 1);
print(A);
reverse(A, 0, A.length - p - 1);
print(A);
reverse(A, A.length - p,A.length-1);
print(A);
}
备注一下交换函数的传值问题:
参数为int*,表明参数为指针,调用的时候需要传入地址,如f(&a);
参数为int&,传引用参数(C++里有引用的概念,C里面貌似没有),调用时用 f(a),“引用类型的形参就通过形实结合,成为实参的一个别名,对形参的任何操作也就会直接作用于实参”。例如下面这个交换代码,若调用为F(A,B):则是对A的引用,函数内对a进行修改实质上是对A所在地址上的值进行修改。
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
因此,f(int * &a)表明参数是指针,同时为传引用参数,对形参的修改将直接作用于实参(int指针本身)。