顺序表的逆置算法

顺序表的逆置算法

  • 1、逆置原理
  • 2、算法实现
  • 3、经典例题1
  • 4、经典例题2

1、逆置原理

顺序表的逆置即将线性表(a1,a2,a3…,an)转化为(an,an-1,an-2…,a2,a1),此操作在程序设计中经常使用。

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;
	}
}
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; 
} 

顺序表的逆置算法_第1张图片

3、经典例题1

题目描述:
已知在一维数组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; 
} 

顺序表的逆置算法_第2张图片
此算法时间复杂度为O(n),空间复杂度O(1)

4、经典例题2

题目描述:
[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张图片
(3)、该算法进行了三次逆置操作,共需进行约n次交换操作,每次交换操作的操作量级为O(1),因此算法时间复杂度为O(n)。该算法原地工作即所需的辅助空间为常量),因而空间复杂度为O(1)。

你可能感兴趣的:(算法合集,算法,数据结构)