数组元素换位算法 加强实用版
今天拜读了
http://community.csdn.net/Expert/topic/5277/5277687.xml?temp=.7706415
一帖各位的回复,原问题是
设a[0:n-1]是一个有n个元素的数组,k(0 <=k <=n-1)是一个非负整数。试设计一个算法将子数组a[0:k]与a[k+1:n-1]换位。要求算法在最坏情况下所用的时间为O(n),且只用到O(1)的辅助空间
我有个想法,倘若不限制辅助空间,但是a数组存储的不是数字,而是非常复杂的对象数据(我的意思是每个对象搬动都比较耗内存),那么如何设计算法呢?
设a[0:n-1]是一个有n个元素的对象数组,k(0 <=k <=n-1)是一个非负整数。试设计一个算法将子数组a[0:k]与a[k+1:n-1]换位。辅助空间不限,要求算法用时越少用存越少越好,不知各位高手有何见解?
[解决办法]
数组内容是不是数字并无区别... 如果是非常大的数据对象,那么数组应该存储指向这个结构的指针,而不是结构本省。。。
[解决办法]
不限辅助空间
还能怎么办,不就是备份小的那一块,然后移动另一块,最后再把先前的那一块放上去
我觉得这些都是必要操作,简化不了
[解决办法]
基本操作定义为 交换两个数。
1. 使用反转的方法,需要 n 个基本操作。
-------------------
先反转a[0:k] : k/2 个基本操作;
再反转a[k+1:n-1] :(n-k-1)/2 个基本操作;
最后反转数组a[n-1..0] : n/2 个基本操作;
====
total = k/2+(n-k-1)/2+n/2 = n 个基本操作;
交换这实际上有3个子步骤。
如果不用辅助空间。
SWAP(a,b){ a ^= b;b ^= a;a^ = b; }
如果使用1个辅助空间 {tmp = a, a=b,b=tmp}.
2。如果不考虑空间限制,当然是定义一个一样大小的数组 b[n]。
for(j=n-1,i=k;i> =0;i--,j--) /*先将A[k..0]放好*/
b[j] = a[i];
for(j=0,i=k+1; i <n;i++,j++) /*再将A[n-1..k+1]放好*/
b[j] = a[j];
没有交换操作,比方法1快3倍,代价是n 个辅助空间。
恐怕不能再快了吧。。。
[解决办法]
最快的算法可以如下:
记
u=k+1
算法的最终目的是将
a[(x+u)%n]移动到a[x]
计算d=(u,n),即d是u和n的最大公约数 (算法时间复杂度O(log(n))可以忽略)
d=n;x=d%u;while(x> 0){d=u;u=x;};d=u;
然后
for(i=0;i <d;i++){
temp=a[i];
for(j=0;j <n/d-1;j++){
a[(j*u+i)%n]=a[((j+1)*u+i)%n];
}
a[(j*u+i)%n]=temp;
}
[解决办法]
利用计数排序啊