题目:
设将n(n>1) 个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置, 即将R中的数据由(X0,X1,…Xn)变换为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1)
思想:通过对元素的置换操作,可以对任意某段顺序表交换后面顺序表的位置。以给出的p为第一个顺序表的终点,然后对整个大的顺序表置换即可!
#include <iostream>
using namespace std;
#define MAXSIZE 50
//静态表
typedef struct{
int data[MAXSIZE];
int length;
} StaticSqlist;
//交换操作
void reverse(StaticSqlist &s,int start,int end){
int temp;
for(int i=start;i<(start+end)/2;++i){
temp = s.data[i];
s.data[i] = s.data[end - i - 1 + start];
s.data[end - i - 1 + start] = temp;
}
}
//三次交换,使得顺序表置换
void moveleft(StaticSqlist &s,int p){
reverse(s,0,p);
reverse(s,p,s.length);
reverse(s,0,s.length);
}
int main(){
StaticSqlist l;
l = {
{1,2,3,4,5},5};
moveleft(l,1);
for(int i=0;i<l.length;i++){
printf("%d,",l.data[i]);
}
return 0;
}
思考:当交换的顺序表发生如下改变时,给出来的结果和执行顺序会有什么不一样?
//三次交换,使得顺序表置换
void moveleft(StaticSqlist &s,int p){
reverse(s,0,p-1);
reverse(s,p-1,s.length-1);
reverse(s,0,s.length-1);
}
分析:
假设:输入数据不变,则按执行函数有如下三步
reverse(s,0,p-1); //此时p-1=0,不执行任何操作
数据此时变化为:1,2,3,4,5
reverse(s,p-1,s.length-1); //此时p-1=0,s.length-1=4,则顺序表倒置1-4号元素
数据此时变化为:4,3,2,1,5,
reverse(s,0,s.length-1); //此时s.length = 4,则顺序表倒置1-4号元素
数据此时变化为:1,2,3,4,5
所以整体顺序表又被转置回来了,输出结果与输入结果一致
假设:输入数据左移动2位,则还是按执行函数有如下三步
reverse(s,0,p-1); //此时p-1=1,由于计算机是向下取整的,(start+end)/2=0,循环不执行任何操作
数据此时变化为:1,2,3,4,5
reverse(s,p-1,s.length-1); //此时p-1=1,s.length-1=4,则顺序表倒置2-4号元素
数据此时变化为:1,