顺序表逆置方法:可以先建立一个新的顺序表b,把顺序表a中的元素逆序输出,但是这种空间复杂度为O(n),浪费空间资源,所以我们从两头分别交换元素,即下标i=0,j=length-1相互交换,然后i++,j--,这样空间的复杂度为O(1)。
这里我采用了两个例子,第一个是经典顺序表逆置算法,讲解比较详细,第二种是进行三次逆置,举一反三,也容易理解。
例1:设计一个高效的算法,将顺序表L中所有元素逆置,空间复杂度为O(1)。
思想:因为要求空间的复杂度为1,所以扫描顺序表的前半部分元素,将其与后半部分元素对换。顺序表的长度为L.length。
图解:
(数字为执行顺序)
代码如下:
void reverse (SqList &L) {
Elemtype temp;
for(i=0;i<L.length/2;i++)
{
temp=L.data[i]; //引入一个中间元素,实现元素的两两对换
L.data[i]=L.data[L.length-i-1];
//L.length-1得到的是最后一位元素的下标,再减去i得到顺序表中和L.data[i]对称的元素下标,例如上图1的下标为i=0,4的下标为length-1-i=4-1-0=3,1对称的元素是4
L.data[L.length-i-1]=temp;
}
}
例2:已知在一维数组A[m+n]中依次存放两个线性表(a1,a2…am)和(b1,b2…bn)。试编写一个函数,将数组中两个顺序表的位置互换。
思想:这个逆置比上一个例子需要多进行两次,先将整个数组原地逆置,再对前n个元素和后m个元素分别逆置。
代码如下:
typedef int Datatype;
void Reverse(Datatype A[ ],int left,int right, int arraySize)
//实现三个逆置操作,left和right分别为最左边和最右边元素的下标
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;
//元素两两对换,rignt为最右边元素的下标,所以不用像例1减1
}
}
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,b3,…,bn),算法将这两个表的位置互换
Reverse (A,0,m+n-1,arraySize) ;
Reverse (A, 0,n-l,arraySize);
Reverse (A,n,m+n-l,arraySize);
}