• 全排序分析


     1 #include<iostream>
     2 using namespace std;
     3 template <typename T>
     4 inline void swap(T* array, unsigned int i, unsigned int j)
     5 {
     6     T t = array[i];
     7     array[i] = array[j];
     8     array[j] = t;
     9 }
    10 
    11 /*
    12 * 递归输出序列的全排列
    13 */
    14 void FullArray(int* array, size_t array_size, unsigned int index = 0)
    15 {
    16     
    17     if (index >= array_size)
    18     {
    19         static int j = 1;
    20         cout << "输出次数" << j++ <<": ";
    21         for (unsigned int i = 0; i < array_size; ++i)
    22         {
    23             cout << array[i] << ' ';
    24         }
    25         cout << '
    ';
    26         
    27     }
    28 
    29     for (unsigned int i = index; i < array_size; ++i)
    30     {
    31         swap(array, i, index);
    32         cout << i << "  :交换" << endl;
    33         for (unsigned int i = 0; i < array_size; ++i)
    34         {
    35             cout << array[i] << ' ';
    36         }cout << endl;
    37         FullArray(array, array_size, index + 1);
    38         swap(array, i, index);
    39         cout << i << "  :恢复" << endl;
    40         for (unsigned int i = 0; i < array_size; ++i)
    41         {
    42             cout << array[i] << ' ';
    43         }cout << endl;
    44     }
    45 }
    46 void main()
    47 {
    48     int n;
    49     cin >> n;
    50     int *p = new int[n];
    51     for (int i = 0; i < n; i++)
    52         p[i] = i;
    53     FullArray(p, n);
    54     delete[]p;
    55 

     总之现在纸上规范化自己平时手动做全排的过程,我们会得到一个树形图。由n!我们可以得到这样一个结论:

    如果从第一位开始从左到右进行选择的话,那么第一位有n种,第二位有n-1种……第n位有1种选择。

    如果我们要设计递归,那就要给程序“分层次”

    红圈圈出来的为第n次函数(第n-1次递归)的循环交换。

    由于我们的程序没法向人一样把排列列出来,电脑每个内存只能存一个东西(别举共用体什么的反驳我///我只是在解释为啥函数要这么设计)

    所以我们要一次生成一个排列。不能像上图那样把每一位的元素都先列好然后在组合起来(横着写),如果是这样内存开销是很大的。我们竖着写,写完一条链后从根节点再引出一条。

    再看我们的函数生成全排的部分:

     1 void FullArray(int* array, size_t array_size, unsigned int index = 0)
     2 {
     3     
     4     if (index >= array_size)
     5     {
     6         static int j = 1;
     7         cout << "输出次数" << j++ <<": ";
     8         for (unsigned int i = 0; i < array_size; ++i)
     9         {
    10             cout << array[i] << ' ';
    11         }
    12         cout << '
    ';
    13         
    14     }
    15 
    16     for (unsigned int i = index; i < array_size; ++i)
    17     {
    18         swap(array, i, index);
    19         FullArray(array, array_size, index + 1);
    20         swap(array, i, index);
    21      }
    22 }

    每次执行到循环语句都是:循环进行一次交换——》进入递归——》(递归中)循环进行一次交换——》下一次递归……直到最内层递归执行完毕后在从内到外执行排序回落(复位)语句。执行完毕后进行最外层第二次循环

  • 相关阅读:
    关于类型转换构造函数的疑惑点
    类模板与静态 成员变量
    模板与友元
    类模板与派生
    类模板
    函数模板
    泛型程序设计基本概念
    3、成员函数
    条款 06:若不想使用编译器自动生成的函数,就该明确拒绝
    PHP操作redis
  • 原文地址:https://www.cnblogs.com/yuelien/p/5423136.html
Copyright © 2020-2023  润新知