题目描述:已知在一维数组A[m + n]中依次存放两个线性表(a1,a2,a3,……,am)和(b1,b2,b3,……,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,……,bn)放在(a1,a2,a3,……,am)的前面。
算法思想
①先把(a1,a2,a3,……,am)逆序为(am,……,a3,a2,a1);
②再把(b1,b2,b3,……,bn)逆序为(bn,……,b3,b2,b1);
③此时数组变为了(am,……,a3,a2,a1, bn,……,b3,b2,b1),观察发现此时将整个数组再逆序一次即可。
代码如下:
一个函数实现版
void Exchange(SeqList &L,int m,int n){
if(m + n != L.length || m < 0 || n < 0){
return;//传入的参数 m,n不合法
}
ElemType temp;//用来交换顺序表的两个元素的临时变量
for(int i = 0;i < m / 2;i++) {
temp = L.data[i];
L.data[i] = L.data[m - i - 1];//交换顺序表前面部分 L[0,...,m]对称位置元素值
L.data[m - i - 1] = temp;
}
for(int j = m,i = 0;j < m + n/2;j++,i++){
temp = L.data[j];
L.data[j] = L.data[L.length - i - 1];//交换顺序表后面部分 L[m,...,m+n]对称位置元素值
L.data[L.length - i - 1] = temp;
}
for(int k = 0;k < L.length / 2;k++){
temp = L.data[k];
L.data[k] = L.data[L.length - k - 1];//交换整个顺序表 L[0,...,m+n]对称位置元素值
L.data[L.length - k - 1] = temp;
}
}
改善:观察发现上述代码冗余代码较多,不够优雅,将数组逆序的for循环部分封装一下,变为下面的版本
封装函数版
void Reverse(SeqList &L,int left,int ArraySize){
ElemType temp;//用来交换顺序表的两个元素的临时变量
for(int j = left,i = 0;j < left + ArraySize/2;j++,i++){
temp = L.data[j];
L.data[j] = L.data[left + ArraySize - i - 1];//交换顺序表对称位置元素值
L.data[left + ArraySize - i - 1] = temp;
}
}
void Exchange(SeqList &L,int m,int n){
if(m + n != L.length || m < 0 || n < 0){
return;//传入的参数 m,n不合法
}
ElemType temp = 0;
Reverse(L,0,m);//交换顺序表前面部分 L[0,...,m]对称位置元素值
Reverse(L,m,n);//交换顺序表后面部分 L[m,...,m+n]对称位置元素值
Reverse(L,0,m+n);//交换整个顺序表 L[0,...,m+n]对称位置元素值
}
完整程序测试:
#include <iostream>
using namespace std;
#define MaxSize 50
typedef int ElemType;
typedef struct{
ElemType data[MaxSize];
int length;
}SeqList;
//顺序表初始化
void InitList(SeqList &L){
for(int i = 0;i < MaxSize;i++){
L.data[i] = 0;//顺序表中所有位置初始化赋值为0
}
L.length = 0;//顺序表长度赋值为0
}
//打印输出顺序表元素
void ListPrint(SeqList L){
for(int i = 0;i < L.length;i++){
printf("%d ",L.data[i]);//循环遍历顺序表,输出顺序表元素
}
printf("\n");
}
//顺序表插入
bool ListInsert(SeqList &L,int i,ElemType e){
if(i < 1 || i > L.length + 1){//顺序表插入位置不合法,报错,结束运行
return false;
}
if(L.length >= MaxSize){//顺序表已满,报错,结束运行
return false;
}
for(int j = L.length;j >= i;j--){
L.data[j] = L.data[j - 1];//将位置i及其之后的元素后移
}
L.data[i - 1] = e;//在顺序表位置i处插入元素
L.length++;//顺序表长度自增一
return true;
}
void Reverse(SeqList &L,int left,int ArraySize){
ElemType temp;//用来交换顺序表的两个元素的临时变量
for(int j = left,i = 0;j < left + ArraySize/2;j++,i++){
temp = L.data[j];
L.data[j] = L.data[left + ArraySize - i - 1];//交换顺序表对称位置元素值
L.data[left + ArraySize - i - 1] = temp;
}
}
void Exchange(SeqList &L,int m,int n){
if(m + n != L.length || m < 0 || n < 0){
return;//传入的参数 m,n不合法
}
ElemType temp = 0;
Reverse(L,0,m);//交换顺序表前面部分 L[0,...,m]对称位置元素值
Reverse(L,m,n);//交换顺序表后面部分 L[m,...,m+n]对称位置元素值
Reverse(L,0,m+n);//交换整个顺序表 L[0,...,m+n]对称位置元素值
}
int main(){
SeqList L;
InitList(L);
ListInsert(L,1,1);
ListInsert(L,2,2);
ListInsert(L,3,3);
ListInsert(L,4,4);
ListInsert(L,5,5);
ListInsert(L,6,6);
ListInsert(L,7,7);
ListInsert(L,8,8);
printf("逆序转换前:");
ListPrint(L);
Exchange(L,3,5);
printf("逆序转换后:");
ListPrint(L);
return 0;
}
测试结果: