全排列算法

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


问题分析:如果给出一个序列,如何枚举出其全排后的子序列?下面通过分析序列“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;
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值