顺序表的逆置即将线性表(a1,a2,a3…,an)转化为(an,an-1,an-2…,a2,a1),此操作在程序设计中经常使用。
#include
#include
using namespace std;
typedef int DataType;
void Reverse(DataType A[],int left,int right,int arraySize){
//逆置(aleft,aleft+1,aleft+2,...,aright)为(aright,aright-1,..,aleft)
if(left >= right || right >= arraySize) return;
int mid = (left + right)/2;
for(int i = 0; i <= mid - left; i++){
DataType temp = A[left+i];
A[left+i] = A[right-i];
A[right-i] = temp;
}
}
int main(){
int n;
cin >> n;
int *A = (int*)malloc(sizeof(int)*n);
for(int i = 0; i < n; i++)
cin >> A[i];
cout << " 逆置前:" << endl;
for(int i = 0; i < n; i++)
cout << A[i] << " ";
cout << endl;
Reverse(A, 0, n-1, n);
cout << " 逆置后:" << endl;
for(int i = 0; i < n; i++)
cout << A[i] << " ";
return 0;
}
题目描述:
已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,a3,…,am)和(b1,b2,b3,…,bn),试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,…,bn)放在(a1,a2,a3,…,am)的前面。
算法设计思想:
对数组进行三次逆置操作:
1、对区间为[0,n+m-1]内的元素进行逆置操作,即将(a1,a2,a3,…am,b1,b2,…bn)逆置为(bn,bn-1,…,b1,am,am-1,…,a1)
2、对区间为[0,n-1]内的元素进行逆置操作,即将(bn,bn-1,…,b1,am,am-1,…,a1)逆置为(b1,b2,…,bn,am,am-1,…,a1)
3、对区间为[n,n+m-1]内的元素进行逆置操作,即将(b1,b2,…,bn,am,am-1,…,a1)逆置为(b1,b2,…,bn,a1,a2,…,am)
算法源码:
#include
#include
using namespace std;
typedef int DataType;
void Reverse(DataType A[],int left,int right,int arraySize){
//逆置(aleft,aleft+1,aleft+2,...,aright)为(aright,aright-1,..,aleft)
if(left >= right || right >= arraySize) return;
int mid = (left + right)/2;
for(int i = 0; i <= mid - left; i++){
DataType temp = A[left+i];
A[left+i] = A[right-i];
A[right-i] = temp;
}
}
void Exchange(DataType A[],int m,int n,int arraySize){
/*数组A[m+n]中,从0到m-1存放顺序表(a1,a2,a3,..,am),从m到m+n-1存放顺序表(b1,b2,...,bn),
算法将这两个表的位置互换*/
Reverse(A, 0, m+n-1, arraySize);
Reverse(A, 0, n-1, arraySize);
Reverse(A, n, m+n-1, arraySize);
}
int main(){
int n,m;
cin >> n >> m;
int *A = (int*)malloc(sizeof(int)*(n+m));
for(int i = 0; i < n + m; i++)
cin >> A[i];
cout << " 交换前:" << endl;
for(int i = 0; i < n + m; i++)
cout << A[i] << " ";
cout << endl;
Exchange(A, n, m, n + m);
cout << " 交换后:" << endl;
for(int i = 0; i < n + m; i++)
cout << A[i] << " ";
return 0;
}
题目描述:
[2010年统考408真题]设将n(n>1)个整数存放到一维数组中R中,设计一个在时间和空间方面都尽可能高效的算法.将R中保存的序列循环左移p(0 < p < n)个位置,即将R中的数据由(X0,X1,…,Xn-1)变换为(Xp,Xp-1,…,Xn-1,X0,X1,…,Xp-1)。要求:
(1)、给出算法的基本设计思想。
(2)、根据设计思想,采用C或C++或Java语言描述算法,并在关键之处给出注释。
(3)、说明你所设计算法的时间复杂度和空间复杂度。
解:(1)、对数组进行三次逆置操作:
①、对区间为[0,n-1]内的元素进行逆置操作,即将(X0,X1,…,Xn-1)逆置为(Xn-1,Xn-2,…,X0)
②、对区间为[0,n-p-1]内的元素进行逆置操作,即将(Xn-1,Xn-2,…,X0)逆置为(Xp,Xp+1,…,Xn-1,Xp-1,Xp-2,…,X0)
③、对区间为[n-p,n-1]内的元素进行逆置操作,即将(Xp,Xp+1,…,Xn-1,Xp-1,Xp-2,…,X0)逆置为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1)
(2)、算法源码:
#include
#include
using namespace std;
typedef int DataType;
void Reverse(DataType A[],int left,int right,int arraySize){
//逆置(aleft,aleft+1,aleft+2,...,aright)为(aright,aright-1,..,aleft)
if(left >= right || right >= arraySize) return;
int mid = (left + right)/2;
for(int i = 0; i <= mid - left; i++){
DataType temp = A[left+i];
A[left+i] = A[right-i];
A[right-i] = temp;
}
}
void Exchange(DataType A[],int n,int p,int arraySize){
/*数组A[n]中,将元素(X0,X1,...,Xn-1)变换为(Xp,Xp-1,...,Xn-1,X0,X1,...,Xp-1)*/
Reverse(A, 0, n-1, arraySize);
Reverse(A, 0, n-p-1, arraySize);
Reverse(A, n-p, n-1, arraySize);
}
int main(){
int n,p;
cin >> n >> p;
int *A = (int*)malloc(sizeof(int)*(n));
for(int i = 0; i < n; i++)
cin >> A[i];
cout << " 移动前:" << endl;
for(int i = 0; i < n; i++)
cout << A[i] << " ";
cout << endl;
Exchange(A, n, p, n);
cout << " 移动后:" << endl;
for(int i = 0; i < n; i++)
cout << A[i] << " ";
return 0;
}
(3)、该算法进行了三次逆置操作,共需进行约n次交换操作,每次交换操作的操作量级为O(1),因此算法时间复杂度为O(n)。该算法原地工作(即所需的辅助空间为常量),因而空间复杂度为O(1)。