顺序表逆转是顺表基本操作之一,本将讨论顺序表逆转的基本方法,以及用顺序表逆转解决实际题目,本文将讨论三个问题
题目一
顺序表逆转
方法:直接循环将首尾元素交换。
void Reverse(Sqlist &L){
int mid = (L.length-1)/2;
for(int i=0; i<=mid; i++){
int tmp = L.data[i];
L.data[i] = L.data[L.length-1-i];
L.data[L.length-1-i] = tmp;
}
}
题目二
已知在一维数组A[m+n]
中一次存放两个线性表
和
。试编写一个函数,将数组中两个顺序表的位置互换,即将
放在
的前面。
思路:首先将数组A[m+n]
中的全部元素
原地逆置为
,在对前n
个元素和后m
个元素分别使用逆置算法,即可得到
,从而实现了顺序表的位置互换。
#include<iostream>
#include<stdio.h>
using namespace std;
struct Sqlist{
int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int length = 10;
};
void Reverse(Sqlist &L, int left, int right){
int mid = (right-left)/2;
for(int i=0; i<=mid; i++){
int tmp = L.data[left-1+i];
L.data[left-1+i] = L.data[right-1-i];
L.data[right-1-i] = tmp;
}
}
int main(){
Sqlist L;
for(int i=0; i<L.length; i++){
printf("%d ", L.data[i]);
}
printf("\n");
Reverse(L, 1, 10);
Reverse(L, 1, 5);
Reverse(L, 6, 10);
for(int i=0; i<L.length; i++){
printf("%d ", L.data[i]);
}
}
题目三
试将
个整数存放到一维数组R
中,设计一个在时间和空间上都尽可能高效的算法。将R
中保存的序列循环左移
个位置,即将R
中的数据由
变换为
。
思路:这个题表面看起来是数组的循环左移,但仔细类比题目二,还是会发现由许多共通之处,同样可以可以看作把数组
转换成
。
#include<iostream>
#include<stdio.h>
using namespace std;
struct Sqlist{
int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int length = 10;
};
void Reverse(Sqlist &L, int left, int right){
int mid = (right-left)/2;
for(int i=0; i<=mid; i++){
int tmp = L.data[left-1+i];
L.data[left-1+i] = L.data[right-1-i];
L.data[right-1-i] = tmp;
}
}
int main(){
Sqlist L;
int n = 3; //循环左移3位
for(int i=0; i<L.length; i++){
printf("%d ", L.data[i]);
}
printf("\n");
Reverse(L, 1, n);
Reverse(L, n+1, 10);
Reverse(L, 1, 10);
for(int i=0; i<L.length; i++){
printf("%d ", L.data[i]);
}
}
- 三次逆转的时间复杂度分别为 和 ,所以这个算法的时间复杂度为 ,空间复杂度为 。
- 当然,循环移动数组还可以采用辅助数组实现,将
R
中前p
个整数依次暂存在S
中,
再将R
中后n-p
个整数左移,最后将S
中暂存的p
个树一次放回到R
中的后续单元。这样做损失了空间复杂度,不是最优的解法。