假使你需要把一个数组随机打乱顺序进行重排。你需要保证重排后的结果是概率均等、完全随机的。下面两种算法哪一种是正确的?其中,
random(a,b)函数用于返回一个从a到b(包括a和b)的随机整数。
for i:=1 to n do swap(a[i], a[random(1,n)]);
for i:=1 to n do swap(a[i], a[random(i,n)]);
也就是洗牌~~
lvp0526说:
后者。设前者任意元素a在第k次交换后处于某一确定位置a[r]的概率为P(k),则第k+1次交换后处于位置r的概率为:P(k+1)=P(k)*(n-1)/n+[1-p(k)]*(1/n)=P(k)*(n-2)/n+1/n,移项得P(k+1)-1/2=[(n-2)/n][P(k)-1/2],等比求通项得P(k+1)-1/2=[P(1)-1/2]*[(n-2)/n]^k,当k=n-1,则P(n)=[P(1)-1/2]*[(n-2)/n]^(n-1)+1/2,又P(1)=1/n,故P(n)显然不恒等于1/n,故n次交换后a位于位置r的概率不是1/n,不随机。