给定一个线性表,如何将其中的元素逆置?可设置两个整型变量 i 和 j,i 指向第一个元素,j 指向最后一个元素,边交换 i 和 j 所指元素,边让 i 和 j 相向而行,直到相遇,实现代码如下。假设元素存于数组a[ ]中,left和right是数组两端元素的下标。
for(int i=lefft,j=right;i<j;i++,j--){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
【例2-5】
(1)将一长度为 n 的数组的前端 k(k<n)个元素逆序后移动到数组后端,要求原数组中数据不丢失,其余元素的位置无关紧要
eg:a b c d e f 前两个元素逆序到数组后端变为 c d e f b a
思路:第一个元素和倒数第一个元素交换,第二个元素和倒数第二个交换...
假设k=2,变换后的结果:f e c d b a,上述说到其余元素位置无关紧要,
所以结果虽然不是 c d e f b a ,但也不是错误的。
void reverse(int a[],int left,int right,int k){ //reverse 反向
int temp;
for(int i=left,j=right;i<left+k && i<j;++i,--j){ //由于限制了是前端的几个元素,所以 i < left+k
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
(2)将一长度为 n 的数组的前端 k(k<n)个元素保持原序移动到数组后端,要求原数组中数据不丢失,其余元素的位置无关紧要
eg:a b c d e f 前两个元素保持原序到数组后端变为 c d e f a b
思路:假设k=2,先逆序前两个元素:b a c d e f ,再逆序整个数组:f e c d a b
上述说到其余元素位置无关紧要,所以结果虽然不是 c d e f a b ,但也不是错误的。
void moveToEnd(int a[],int n,int k){
reverse(a,0,k-1,k);
reverse(a,0,n-1,n);
}
(3)将数组中的元素(X0,X1,…,Xn-1),经过移动后变为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1),即循环左移 p(0<p<n)个位置
eg:a b c d e f 左移动 2 个位置变为 c d e f a b
思路:先逆序前两个元素:b a c d e f ,再逆序后面四个元素:b a f e d c ,最后逆序整个数组: c d e f a b
//口诀:左移就是逆前逆后再逆整
void moveP(int a[],int n,int p){
reverse(a,0,p-1,p);
reverse(a,p,n-1,n-p);
reverse(a,0,n-1,n);
}
拓展:即循环右移 p(0<p<n)个位置
eg:a b c d e f 右移动 2 个位置变为 e f a b c d
思路:先逆序后两个元素:a b c d f e,再逆序前面四个元素:d c b a f e ,最后逆序整个数组:e f a b c d
//口诀:右移就是逆后逆前再逆整
void moveP(int a[],int n,int p){
reverse(a,n-p,n-1,p);
reverse(a,0,n-p-1,n-p);
reverse(a,0,n-1,n);
}
小结