对排列进行排序的算法

Algorithm that sorts a permutation

本文关键字:算法 排序 排列      更新时间:2023-10-16

我陷入了这个问题:


给定{0,1,2,…,n-1}的置换p
(此处n=P长度)

解释为什么以下算法按递增顺序对排列进行排序,并给出最坏情况(伪代码)

PermutationSort(P)
    for i = 0 to P.length - 1
        while(P[i] != i)
            t = P[i]
            exchange P[i] with P[t]

(C++代码)

void PermutationSort(int P[], int len)
{
    for(int i = 0; i < len; i++)
        while(P[i] != i)
        {
            int tmp;
            tmp = P[i];
            P[i] = P[tmp];
            P[tmp] = tmp;
        }
}

我完全不知道为什么它会对排列p进行排序。

我整天都在研究这个问题,但我仍然不明白为什么它对排列进行排序。

"用p[p[i]]交换p[i]"做什么?为什么我们最终会得到p[i]=i,这将终止内环?

谢谢你的任何提示或帮助。

首先,请注意,如果从任意元素k开始,并重复应用置换p以获得链式(kpk)→PPk))→PPPk))→…),您将(因为置换P中的元素总数是有限的,并且置换从不将两个输入映射到同一输出)最终返回k。元素的循环(k→Pk)→PPk))→rarrk)称为Pk的轨道,并且置换的每个元素恰好属于一个这样的循环。

现在,让我们看看算法的内部循环对包含元素i的循环做了什么。

如果pi )=i,即如果该元素已经在其所属的位置,则内部循环什么也不做,外部循环继续移动到下一个元素。如果Pi&shinsp;)≠i,然而,内部循环设置t=Pi

交换后,p的新值(t )是pi&lhinsp;)的旧值,即t。因此,元素t现在被正确排序,而Pi 如果这是i,那么循环中就没有更多的元素了,内部循环结束;否则,包含i的循环收缩了一个元素,并且内部循环重复。

因此,在内部循环结束时,所有曾经是i相同循环的一部分的元素(包括i本身)都被移动到了它们的正确位置,从而从循环中删除,而排列的其余部分没有改变。

由于外循环在排列中的每个元素上迭代,因此还保证访问每个循环至少一次。当然,我们正在修改内部循环中的排列,但这没关系,因为内部循环永远不会创建新的循环(多个元素);它只能分解现有的。

因此,原始排列中的每个循环第一次被外循环访问时,内循环对该循环进行排序并分解;在随后访问同一个原始循环时,该循环已经被排序,因此内部循环什么也不做。

这种观察还应该允许您绑定内部循环可以执行的次数,从而确定算法的时间复杂性。