对于HeapAlgorithm的理解

在学全排列算法的时候强行被布置了打一遍Heap’sAlgorithm。于是习惯性的去百度。。发现百度里关于这个的资料很少。但是这个算法很古怪。和现在百度上的那些全排序不同,百度上递归的都是先固定头部,再排后面这样递归先去,这个全排序里面奇偶的全排序操作是不同的。导致了在我看来迷一样的像随机排序。可是结果却一点也不重复,然后就愚蠢的研究了下(用我小学来的出的方法)。想写一点我的理解。但规律问题还是没有解开。求高人后面留言解答。谢谢~(发自内心的!)
首先:关于这个算法。百度百科里有详细的步骤这里写图片描述
但是。可能我比较笨。无法理解。为什么这样换就能做到全排列??!!
然后我就用java先把代码给打了出来。


public class HeapAlgorithm 
{
    public static void main(String[] args) 
    {
        char[] arry={'a','b','c'};
        generate(3,arry);
    }
    private static void generate(int n,char[] arry)
    {
        if(n==1)
      System.out.println(String.valueOf(arry));
        else
        {
            for(int i=0;i<n-1;i+=1)
            {
                generate(n-1,arry);//用于每种情况的一开始打印
                if(n%2==0)
                    swap(arry,i,n-1);
                else
                    swap(arry,0,n-1);
            }
            generate(n-1,arry);//用于用于交换后的打印
        }
    }
    private static void swap(char[] arry,int a,int b)
    {
        char temp=arry[a];
        arry[a]=arry[b];
        arry[b]=temp;
    }
}   

然后我们就开始尝试了。就先从abc开始全排列
这里写图片描述
我运行了三次。可以发现一开始由于for循环里的第一个generate函数。就直接把abc给按顺序给输出了。所以单纯的我认为。for循环里的第一个generate是用于输出交换前的状态。
由于我是三个数。所以当输出的时候其实嵌套了三个函数。输出后回溯一个函数。我们此时的n值为2。然后开始交换。就是第0个和n-1个交换前面开始全排列了。后面的一个数保持不动。
这里写图片描述
就我们这abc情况而言。应该已经交换玩了。所以就应该到后面一个generate去输出答案。bac
输出后再次回溯。就是当n=3的情况。回来了最外面的函数了。然后开始交换。先是奇数。所以是第一个和最后一个开始交换。然后就到下一层。。变成cab
有了刚刚的经验。我们应该能想到下面就会是acb,
bca,cba这里写图片描述看着这个结果。我好像找到了一点点规律。但是不确定。于是我们再来看下到4个数结果这里写图片描述
哈哈。看。首先最后一位都是
固定住了。是dcba。然后再深入。只看末尾是d的数。倒数第二位数是cba,再到里面就会发现。这样奇偶分开的操作居然也能这样有规律的的全排列。而且操作数排序的规律是从后往前固定排序的(和百度里的那种全排序相反。。23333 ps:不要以为是dcba cba这样的顺序。到了第五个你们就会发现莫名其妙的变成了ebcda)
然后就是问题的关键了。为什么要分奇偶去分别操作呢?

愚蠢的我再次采用找规律的方式这里写图片描述
这里。最后一个我把它定义为n。为了我方便查找规律。发现好像发现了一点。主要的交换是在头部,两个交换的最多。其次是第一位和第三位,再其次是第四位。只是这样看。有没有感觉。好像只是头和前面的数交换?根本不用区分奇偶?
然后我们再来看看当5个数的时候n的规律!这里写图片描述
幺蛾子来了。。。神他妈c和d交换。。b和a交换。交换的时候都是偶数。而为什么是偶数?我们拿数据来看。当只有两个数的时候是有2个结果。3个数6个结果。n个数n!个结果。n!肯定是偶数。然后我们只看n就不够了。这是得把i一起加上。我们把i放在n的前面一位!这里写图片描述
如果把i拆分成6个一看(就是3个数全排列的结果)。就发现。第零次是0开头,第一次的六是0开头。第二次是1开头第三次是2开头。
然后我们可能会假想。会不会然后出来第三波是3开头的?这里写图片描述这里写图片描述
然后我对这些数据做了个简化处理。把i为0的给去除掉。
发现能够输出来的。n也有规律。。4和6。。i为3的只有一个。交换的根据算法来说是c和d。这样下去。。
然后我就懵逼了。。但至少我解决了。。知道为啥要分奇偶。因为通过数据来看要达到全排列。肯定得全部轮换一遍而奇数的条件在有5个数的时候起作用。但是无法理解。为啥不是头和第4个数去交换?而是第2个数去交换。那个外国的高人是怎么想到n的规律?和这个交换顺序直接的关系?让它做到全排列并且不重复!。还有个神奇的规律没有探索。呢就是最后一位数字。。它的规律也很神奇啊。一到4位的时候都是dcba这样倒过来。到了第五位就开始跳了。(加入奇数变化)ebcda 到了6位数就成为了febcda。真是让我百思不得骑姐。。。希望有高人来帮忙解答下我的白痴问题。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章