输出数组的全排列方法

参考:点击打开链接

1 递归方法求全排列

// 数组的全排列.cpp : 定义控制台应用程序的入口点。
//程序猴6.27

#include "stdafx.h"
template<typename T> void Swap(T &A,T &B)
{
	T Tmp = A;
	A = B;
	B = Tmp;
}

//判重复元素函数,如果第[Begin,End)之间有元素和第End元素相等,则不执行交换Begin和End元素,
//因为交换它两与交换Begin和End之前与End元素相同的元素产生的结果一致
template<typename T> bool IsSwap(T A[],int Begin,int End)
{
	while(Begin<End)
	{
		if (A[Begin]==A[End])
		   return false;
		Begin++;
	}
	return true;
}

template<typename T> void Permutation(T A[],int Begin,int N)
{
	if (Begin == N)
	{
		for(int i=0;i<N;i++)
			printf("%d",A[i]);
		printf("\n");
	}
	else
	{
		for(int i=Begin;i!=N;i++)
		{
			if (IsSwap(A,Begin,i))
			{
			Swap(A[i],A[Begin]);     //先让第i个元素和开始的第Begin个元素互换
			Permutation(A,Begin+1,N);//然后求后面第Begin+1~END个元素的全排列,并输出
			Swap(A[Begin],A[i]);     //再恢复第i个元素和开始的第Begin个元素
			}

		}
	}
	return;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int A[5] = {1,2,2,4,5};
	int N = 3;
    Permutation(A,0,N);
	return 0;
}


2 非递归算法

template<typename T> void ReverseTail(T A[],int Begin,int End) //摆尾
{
	while(Begin<End)
		Swap(A[Begin++],A[End--]);
}

template<typename T> bool NextPermutation(T A[],int N)
{
	if (N==1)
	  return false;
	int p,q,End,Find;
	End = N-1;
	p = End;
	while (p!=0)
	{
		q = p;
		p--;
		if (A[p]<A[q])
		{
			Find = End;
			while(A[p]>=A[Find])
				Find--;
			Swap(A[p],A[Find]);
			ReverseTail(A,q,End);  //反转q~End元素,方便再次查找全排列
			return true;
		}
	}
	ReverseTail(A,0,End);
	return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int A[5] = {5,1,2,4,2};
	int N = 5;
    //Permutation(A,0,N);
	QuickSort(A,N); //先将原始序列排序
	printf("排序后的原始序列\n");
	for(int i=0;i<N;i++)
		printf("%d",A[i]);
	printf("\n");
	printf("全排列\n");
	do 
	{
		for(int i=0;i<N;i++)
			printf("%d",A[i]);
		printf("\n");
	} while (NextPermutation(A,N));//查找下一个排列
	return 0;
}


运行结果:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值