全排列算法

设R={r1,r2,r3....rn}是要进行排列的n个元素,, Ri=R-{ri} . 集合X中元素的全排列记为Perm(X). (ri)Perm(x)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列,R的全排列可归纳定义为:

  • 当n=1时,Perm(R)={r},其中r是集合R中唯一的元素
  • 当n>1时,Perm(R)是由(r1)Perm(R1),(r2)Perm(R2).......,(rn)Perm(rn)构成,即固定一个元素,对后面的元素进行全排列

如果arr为{'a','b','c','d'}, 则

  • Perm(arr,1)的结果按顺序为: abcd,abdc,acbd,acdb,adcb,adbc. 可见第一个字母都为a.
  • Perm(arr,2)的结果为: abcd,abdc, 可见前两个字母都为ab

arr[k:m]的全排列包含arr[k+1:m]的全排列

//产生前缀是char[0:k-1],后缀是str[k:str.Length]的全排列,k=0,则产生str[0:str.Length]的全排列
        public static void Perm<T>(T []arr ,int k) where T:struct
        {
            if (k == arr.Length)
            {
                Output(arr);
            }
            else
            {
                for (int i = k; i < arr.Length; i++)
                {
                    Swap(ref arr[k],ref arr[i]);
                    Perm(arr,k+1);
                    Swap(ref arr[k],ref arr[i]);
                }
            }
        }

     private static void Swap<T>(ref T a,ref T b) where T:struct
        {
            T temp = a;
            a=b;
            b = temp;
        }

        private static void Output<T>(T[] arr)
        {
            foreach (T item in arr)
            {
                Console.Write(item + " ");
            }
            Console.WriteLine();
        }
原文地址:https://www.cnblogs.com/phenixyu/p/5399234.html