如何求1到N的数的全排列

// 求N个数的全排列
   
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;

#define N 5

int n = 0;
void output(int str[N], int begin)
{
	if (begin == N - 1)
	{
		for (int i = 0; i < N; i++)
		{
			cout<<str[i]<<"\t";
		}
		cout<<endl;
		n++;
		return;
	}
	for (int p = begin; p < N; p++)
	{
		int t = str[p];
		str[p] = str[begin];
		str[begin] = t;
		output(str, begin+1);
		t = str[p];
		str[p] = str[begin];
		str[begin] = t;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int a[N],i;
	for (i = 0; i < N; i++)
	{
		a[i] = i+1;
	}
	cout<<"所有的排序:"<<endl;
	output(a, 0);
	cout<<endl<<"共有 "<<n<<"种"<<endl;
	system("pause");
	return 0;
}


      这是递归算法,相应的时间复杂度和空间复杂度会很大,下面是非递归算法:

      要考虑全排列的非递归实现,先来考虑如何计算字符串的下一个排列。如"1234"的下一个排列就是"1243"。只要对字符串反复求出下一个排列,全排列的也就迎刃而解了。

      如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"、"52"都是非递增的,"26 "即满足要求,称前一个数字2为替换

数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0、2都不行,5可以,将5和2交换得到"956220",然后再将替换点后的字符"6220"颠

倒即得到"950226"。对于像"4321"这种已经是最“大”的排列,采用STL中的处理方法,将字符串整个颠倒得到最“小”的排列"1234"并返回false。这样,只要一个循环再加上计算

字符串下一个排列的函数就可以轻松的实现非递归的全排列算法。按上面思路并参考STL中的实现源码,不难写成一份质量较高的代码。值得注意的是在循环前要对字符串排序

下!

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
//交换数组a中下标为i和j的两个元素的值
void swap(int* a,int i,int j)
{
	a[i]^=a[j];
	a[j]^=a[i];
	a[i]^=a[j];
}
//将数组a中的下标i到下标j之间的所有元素逆序倒置

void reverse(int a[],int i,int j)
{
	while (i < j)
		swap(a,i++,j--);
}
void print(int a[],int length)
{
	for(int i=0;i<length;++i)
		cout<<a[i]<<" ";
	cout<<endl;
}
//求取全排列,打印结果
void combination(int a[],int length)
{
	if(length<2) return;
	while(true)
	{
		print(a,length);
		int i,j; 
		for(i=length-2;i>=0;--i) //找升序的相邻2数,前一个数即替换数 
		{
			if(a[i]<a[i+1]) break;
			else if(i==0) return;
		}
		for(j=length-1;j>i;--j) //从后往前找到替换点后第一个比替换数大的数
			if(a[j]>a[i]) break;
		swap(a,i,j); 
		reverse(a,i+1,length-1); //将替换点以后的序列反转
	}
}
int QsortCmp(const void *pa, const void *pb)  
{  
	return *(char*)pa - *(char*)pb;  
}
int main()
{
	int arr[5] = {1,2,3,4,5};
	qsort(arr, 5, sizeof(arr[0]), QsortCmp); //排序之前先将数组递增排序
	combination(arr, 5);
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值