对排列进行排序的算法

时间:2015-04-04 08:41:42

标签: c++ algorithm sorting permutation

我遇到了这个问题:


给定{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进行排序。

我整天都坐在这个问题上,但我仍然没有为什么对排列进行排序。

什么&#34;用P [P [i]]&#34;交换P [i];为什么我们最终得到P [i] = i然后终止内循环呢?

感谢任何提示或帮助。

1 个答案:

答案 0 :(得分:1)

首先,请注意,如果从任意元素 k 开始,并重复应用排列 P 以获得类似链( k >→ P k )→ P P k ))→ P P P k )))→...),你会(因为总数)置换 P 中的元素数量是有限的,并且置换从不将两个输入映射到相同的输出)最终在 k 处结束。 cycle元素(k→ P k )→ P P k ))→...→ k )在 P 下被称为 k orbit,并且排列的每个元素都属于这样一个循环。

现在,让我们看一下你的算法的内循环对包含元素 i 的循环的作用。

如果 P i )= i ,即如果这个元素已经属于它,那么内部循环什么也不做外部循环移动到下一个元素。但是,如果 P i )≠ i ,则内循环设置 t = P i ),然后修改排列 P 以交换 P i )和 p 的()。

交换后, P t )的新值是 P 的旧值( i ),即 t 。因此,元素 t 现在已正确排序,而 P i )现在包含旧值 P t )= P P i )),即循环中的(前)下一个元素。如果这是 i ,则循环中不再剩余元素,内循环结束;否则,包含 i 的循环已缩小一个元素,内循环重复。

因此,在内循环结束时,所有与 i (包括 i 本身)相同循环的元素都已移至它们的正确位置,因此从循环中移除,而其余的排列没有改变。

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

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

此观察还应允许您限制内循环执行的次数,从而确定算法的时间复杂度。