Loading

全排序分析

 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 << '\n';
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 << '\n';
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 }

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

posted @ 2016-04-22 22:56  ArkiWang  阅读(255)  评论(2编辑  收藏  举报