全排列的递归算法

本文介绍如何使用递归算法生成给定集合的所有排列,并通过C++中的algorithm库简化此过程。通过实例演示,从集合{a, b, c}

    给定由n(n≥1)个元素组成的集合,输出该集合所有可能的排列。例如,集合{a,b,c}的所有的可能排列为{(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)}。显然,给定n个元素,共有n!个可能的排列。如果给定的集合是{a,b,c,d},可以用下面给出的简单算法来产生其所有可能的排列,即{a,b,c,d}的所有可能的排列由下列的排列组成:

(1)以a开头后面跟着(b,c,d)的所有排列

(2)以b开头后面跟着(a,c,d)的所有排列

(3)以c开头后面跟着(a,b,d)的所有排列

(4)以d开头后面跟着(a,b,c)的所有排列

那么可以得到递归的全排列产生算法:

void perm(char *str,int i,int n)
{
	int j,temp;
	if (i == n) {
		for(j = 0; j <= n; j++)
			printf("%c ",str[j]);
		printf("\n");
	}
	else{
		for(j = i; j <= n; j++){
			swap(str+i,str+j);
			perm(str,i+1,n);
			swap(str+i,str+j);
		}
	}
}
在C++中可以利用algorithm库中的next_permutation可以方便地获得全排列:

template <class BidirectionalIterator>
bool next_permutation (BidirectionalIterator first,
                                    BidirectionalIterator last );

template <class BidirectionalIterator, class Compare>
bool next_permutation (BidirectionalIterator first,
                                      BidirectionalIterator last, Compare comp);
<algorithm>

[ACTION]Transform range to next permutation

Rearranges the elements in the range [first, last) into the lexicographically next greater permutation of elements. The comparisons of individual elements are performed using either operator< for the first version, or comp for the second.

A permutation is each one of the N! possible arrangements the elements can take (where N is the number of elements in the range). Different permutations can be ordered according on how they compare lexicographicaly to each other; The first such-sorted possible permutation (the one that would compare lexicographically smaller to all other permutations) is the one which has all its elements sorted in ascending order, and the largest has all its elements sorted in descending order.

If the function can determine the next higher permutation, it rearranges the elements as such and returns true. If that was not possible (because it is already at the largest), it rearranges the elements according to the first permutation (sorted in ascending order) and returns false.

[PARAMETERS]first, last
Bidirectional iterators to the initial and final positions of the sequence. The range used is[first,last), which contains all the elements between first and last, including the element pointed by first but not the element pointed by last.
comp
Comparison function object that, taking two values of the same type than those contained in the range, returns true if the first argument is to be considered less than the second argument.

[RETURN VALUE]true if the function could rearrange the object as a lexicographicaly greater permutation. Otherwise, the function returns false to indicate that the arrangement is not greater than the previous, but the lowest possible (sorted in ascending order).

测试程序:

void main()
{
	char s[] = "abcd";
	//perm(s,0,3);
	do
	{
		for(int i = 0; i < 4; i++)
			printf("%c ",s[i]);
		printf("\n");
	}while(next_permutation(s,s+4));
}
测试输出:

a b c d 
a b d c 
a c b d 
a c d b 
a d b c 
a d c b 
b a c d 
b a d c 
b c a d 
b c d a 
b d a c 
b d c a 
c a b d 
c a d b 
c b a d 
c b d a 
c d a b 
c d b a 
d a b c 
d a c b 
d b a c 
d b c a 
d c a b 
d c b a 

若修改输入参数
char s[] = "bcad";
则输出为:

b c a d 
b c d a 
b d a c 
b d c a 
c a b d 
c a d b 
c b a d 
c b d a 
c d a b 
c d b a 
d a b c 
d a c b 
d b a c 
d b c a 
d c a b 
d c b a 

以下为你展示Python实现全排列递归算法: 1. **第一种递归实现(通过输入列表生成全排列)** ```python lst = list(input()) lst.sort() n = len(lst) result = [0] * n used = [False] * n def permutation(i): if i == n: for x in result: print(x, end="") print("") return for k in range(n): if not used[k]: result[i] = lst[k] used[k] = True permutation(i + 1) used[k] = False permutation(0) ``` 此代码从用户输入获取列表,对其排序后,利用递归函数`permutation`生成全排列。`used`列表用于标记元素是否已被使用,`result`列表存储当前排列,当`i`等于列表长度时,输出当前排列,否则尝试将未使用元素加入排列并递归调用函数,之后回溯取消使用标记 [^4]。 2. **另一种递归实现思路(利用递归生成全排列)** ```python def permute(nums): result = [] def backtrack(path, used): if len(path) == len(nums): result.append(path[:]) return for i in range(len(nums)): if not used[i]: path.append(nums[i]) used[i] = True backtrack(path, used) used[i] = False path.pop() used = [False] * len(nums) backtrack([], used) return result nums = [1, 2, 3] print(permute(nums)) ``` 这段代码定义了`permute`函数,内部的`backtrack`函数是递归核心。`used`列表标记元素是否使用,`path`存储当前排列,当`path`长度等于输入列表长度时,将当前排列添加到结果列表,否则尝试将未使用元素加入`path`并递归调用`backtrack`,之后回溯取消使用标记并移除元素 [^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值