普通移位:
若數組想從某一位開始向右移n位,一般是從數組的最后一位開始逐次向右移位。
程序如下:
1 #include <iostream>
2 #include <stdlib.h>
3 using namespace std; 4 int s[11]={1,2,3,4,5,6,7,8,9,0}; 5 void main() 6 { 7 for (int i=0;i<11;i++) 8 { 9 cout<<s[i]; 10 } 11 cout<<endl; 12 //移位代碼,此地假設向右移移位
13 for (int j=10;j>0;j--) 14 { 15 s[j]=s[j-1]; 16 } 17 for (int k=0;k<11;k++) 18 { 19 cout<<s[k]; 20 } 21 cout<<endl; 22 }
程序運行結果截圖:
循環移位,下面是自己編的一個:
1 #include<iostream>
2 #include<stdlib.h>
3 using namespace std; 4 int s[10]={1,2,3,4,5,6,7,8,9,0}; 5 void main() 6 { 7 int temp; 8 //向右循環移位3位
9 for(int i=1;i<=3;i++) 10 { 11 temp=s[9]; 12 for(int j=9;j>=1;j-- ) 13 { 14 s[j]=s[j-1]; 15 } 16 s[0]=temp; 17 } 18 for(int k=0;k<=9;k++) 19 { 20 cout<<s[k]; 21 } 22 }
其實原理就是通過一個間接的變量,對數組進行移位。假設數組長度為N,需要循環右移K次,則算法的復雜度為O(K*N),當K>N時算法的復雜度甚至大於O(N^2)。
運行結果圖:
通過分析可以發現,K>N時所移動的位數和K'=K%N相同,如是衍生出如下算法:
1 #include<iostream>
2 #include<stdlib.h>
3 using namespace std; 4 int s[10]={1,2,3,4,5,6,7,8,9,0}; 5 void main() 6 { 7 int temp; 8 int K,KK; 9 K=99; 10 //向右循環移位K位
11 KK=K%10;//數組長度為10
12 for(int i=1;i<=K;i++) 13 { 14 temp=s[9]; 15 for(int j=9;j>=1;j-- ) 16 { 17 s[j]=s[j-1]; 18 } 19 s[0]=temp; 20 } 21 for(int k=0;k<=9;k++) 22 { 23 cout<<s[k]; 24 } 25 cout<<endl; 26 }
運行結果略。
在網上找到一種復雜度為:O(N)的方法,原理如下:
假設原序列為:abcd1234
移位4位后為:1234abcd
移位過程可以表示成如下步驟:
逆序排列abcd:dcba1234
逆序排列1234:dcba4321
逆序排列dcba4321:1234abcd
也就是說需要編寫一個逆序函數,並進行三次逆序變換。
代碼如下:
1 #include<iostream>
2 #include<stdlib.h>
3 using namespace std; 4 void Reverse(int *arr,int b,int e); 5 int s[10]={1,2,3,4,5,6,7,8,9,0}; 6 void main() 7 { 8 int k,kk,N; 9 N=10; 10 k=99; 11 kk=k%10; 12 //下面為循環移位部分
13 Reverse(s,0,N-kk-1); 14 Reverse(s,N-kk,N-1); 15 Reverse(s,0,N-1); 16 //顯示
17 for(int i=0;i<=9;i++) 18 { 19 cout<<s[i]; 20 } 21 cout<<endl; 22 } 23 void Reverse(int *arr,int b,int e) 24 { 25 int temp; 26 for(;b<e;b++,e--) 27 { 28 temp=arr[e]; 29 arr[e]=arr[b]; 30 arr[b]=temp; 31 } 32 }