全排列(递归算法)

本文详细介绍了全排列的概念及其计算公式,并通过递归算法实现全排列的过程。提供了完整的C++代码示例,帮助读者理解全排列算法的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.                                 全排列算法

首先:什么是全排列=》百度一下

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

公式:全排列数f(n)=n!(定义0!=1)

 

算法:递归算法=》网络上偷了一个图

 


全排列:顺便复习一个数学公式

排列的定义:从n个不同元素中,任取m(m≤n,m与n均为自然数,下同)个元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列;从n个不同元素中取出m(m≤n)个元素的所有排列的个数,叫做从n个不同元素中取出m个元素的排列数,用符号 A(n,m)表示。

 

计算公式:

 

组合的定义:从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。用符号 C(n,m) 表示。

计算公式:  ;C(n,m)=C(n,n-m)。(n≥m)

 

排列和组合的区别:

看问题是否和顺序有关。有关就是排列,无关就是组合。 排列:比如说排队问题甲乙两人排队,先排甲,那么站法是甲乙,先排乙,那么站法乙甲,是两种不同的排法,和先排还是后排的顺序有关,所以是A(2,2)=2种

组合:从甲乙两个球中选2个,无论先取甲,在是先取乙,取到的两个球都是甲和乙两个球,和先后取的顺序无关,所以是C(2,2)=1种

 

#include<iostream>
using namespace std;
//交换
void swap(int &a , int &b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
 } 
 //全排列递归算法
void Perm(int list[] , int k ,int m) 
{
	//list 数组存放排列的数,K表示层 代表第几个数,m表示数组的长度
	if(k==m)
	{
		//K==m 表示到达最后一个数,不能再交换,最终的排列的数需要输出;
		for(int i=0 ;i<=m ;i++)
		 cout<<list[i];
		 cout<<endl; 
	 } 
	 else{
	 	for(int i=k;i<=m;i++)
	 	{
	 		swap(list[i],list[k]);
	 		Perm(list,k+1,m);
	 		swap(list[i] , list[k]);
		 }
	 }
	 
}
int main(void)
{
   int a[]={1,2,3};
   int m=2;
   Perm(a,0,2);
	/*
  123
  132
  213
  231
  321
  312
*/
 } 

算法解析思路树解释

 


每次固定几位数,最后只剩一位数,输出,在从后面递归返回上一层,交换在输出

 

        for(int i=k;i<=m;i++)

             {

                    swap(list[i],list[k]);

                    Perm(list,k+1,m);

                    swap(list[i] , list[k]);

               }

代码解析”” int i=k K表示固定了几位数,当前数组交换的临界的位置

 1,2,3,4 当K=0的时候 {1,2,3,4} =》1是固定的 K+1递归

{1}p{2,3,4},K=1,I=1 数组交换只能list[1],list[2],list[3]交换 k=i ,就是为了作为一个标识。


转载于:https://www.cnblogs.com/love-life-insist/p/9062936.html

### C语言实现升序全排列递归算法 为了生成升序的全排列,在编写C语言代码时,可以采用递归方法来处理这个问题。下面是一个具体的例子: ```c #include <stdio.h> #include <string.h> // 打印当前数组状态 void printArray(char *array, int size) { for (int i = 0; i < size; ++i) printf("%c", array[i]); printf("\n"); } // 检查字符是否已经在数组中存在 bool contains(const char *str, int start, int end, char ch) { for (int i = start; i <= end; ++i) if (str[i] == ch) return true; return false; } // 递归函数用于生成全排列 void permuteInOrder(char *chars, bool *used, char *current, int index, int length) { if (index == length) { // 当前索引等于长度,则打印结果 printArray(current, length); return; } for (int i = 0; i < strlen(chars); ++i) { if (!contains(current, 0, index - 1, chars[i])) { // 防止重复元素进入同一位置 current[index] = chars[i]; used[i] = true; permuteInOrder(chars, used, current, index + 1, length); // 回溯操作 used[i] = false; } } } // 初始化调用接口 void generatePermutations(char *inputString, int n) { int len = strlen(inputString); char result[n]; // 存储每次的结果 memset(result, '\0', sizeof(result)); bool visited[len]; for (int i = 0; i < len; ++i) visited[i] = false; qsort(inputString, len, sizeof(char), (int(*)(const void*, const void*))strcmp); // 排序输入字符串以确保顺序性[^3] permuteInOrder(inputString, visited, result, 0, n); } ``` 上述代码实现了基于给定字符集`inputString`按照字典序输出指定长度`n`的所有可能组合的功能。这里的关键在于通过`qsort()`预先对输入进行了排序,从而保证了最终得到的是有序序列。 #### 函数解释: - `printArray`: 输出当前形成的排列。 - `contains`: 判断某个字符是否已经存在于当前位置之前的排列部分。 - `permuteInOrder`: 主要负责递归构建每一个新的排列项,并利用回溯法尝试不同的可能性直到形成完整的排列为止。 - `generatePermutations`: 提供了一个简单的API入口,接受原始字符列表以及期望获得的排列长度作为参数。 此方案不仅考虑到了避免重复元素在同一位置上的放置问题,还通过对初始字符集进行预排序的方式保障了输出结果遵循严格的字典序规则[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值