全排列算法

来源:互联网 发布:hbuilder app源码下载 编辑:程序博客网 时间:2024/06/09 17:37

问题引出:对于一个序列,如果需要知道其全排列有多少种方案,我们可以很快地用数学知识求得全排列后的子排列方案数目,但是如果需要全部罗列出来那些全排列的结果,那么怎么实现呢?


问题分析:如果给出一个序列,如何枚举出其全排后的子序列?下面通过分析序列“1234”,给出其全排列。

  • 首先我们排列出第一个数,如果我们第一次选择1,那么后面的步骤则是全排列“234”;如果是2,那么后面的步骤则是全排列“134”;如果是3,那么后面的步骤则是全排列“214”;如果是4,那么后面的步骤则是全排列“231”。(此处隐晦地指出每一次的如果之前的序列都是“1234”,所以实现的时候当本次全排列结束后,需要将序列恢复至原序列的顺序)
  • 排好第一个数后,后面的部分很容易知道使用相同的方法来实现,因此本算法使用递归比较容易实现。
问题解答:

sort.h

#pragma once#include <iostream>#include <stdio.h>namespace sos{namespace math{size_t Factorial(size_t n);}template<typename T>void Swap(T& a, T&b){T t = a;a = b;b = t;}namespace sort{template<typename T>void FullArray(T* pData, size_t nLen, T* pp=NULL){T* pRst = pp==NULL? pData:pp;if (nLen == 1){static size_t nCount = 0;printf("%-8d %s\n", ++nCount, pRst);}for (size_t i = 0; i < nLen; i++){Swap(pData[0], pData[i]);FullArray(pData + 1, nLen - 1, pRst);Swap(pData[0], pData[i]);}}}}

sort.cpp

#include "sort.h"size_t sos::math::Factorial(size_t n){size_t nRst = 1;while (n > 1){nRst *= n--;}return nRst;}

main.cpp

#include "sort.h"#include <stdio.h>int main(){char p[]="1234";size_t nLen = sizeof(p) / sizeof(p[0]) - 1;sos::sort::FullArray(p, nLen);printf("get %d subsort\n", sos::math::Factorial(nLen));return 0;}

运行结果:


0 0