详解递归实现全排列(赋例题)

目录

引入:

 算法介绍:

例题及代码实现:


引入:

排列组合:

                排列组合是组合学最基本的概念。所谓排列,就是指从给定个数的元素中取出指定个数的元素进行排序组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。

               通过C语言实现排列组合,然后再排列组合中加入适当的判断,便可以利用电脑进行简单的逻辑推理!

 算法介绍:

       排列方式:将所需排列的每个元素按照顺序写入第一个位置,再将剩下的的元素按照顺序写入第二个位置,以此类推,将全部元素写入每个位置中。需要注意的是再每个元素写入后需要将其换回,使每次排列后还能使每个元素回到输入时的位置,这样才能保证下一次分配位置的时候是另一种不同的分类,不会导致重复排序。

人为排列思维方式:

         例:排列1 2 3这三个数

                输入顺序为1 2 3        

                第一次排序:将1 2 3 三个数分别写入第一个空

                        1 _ _       

                         2 _ _

                        3 _ _

                第二次排序:

                        将每个排列后的剩下的元素依次写入第二个空

                         12 _                13 _                

                         21 _                23 _                   

                         31 _                32 _                        

                    第三次排序:

                         将剩下的元素写入第三个空

                         123               132                

                         213                231                    

                         312                321

上述排列过程主要是人们思考时采用的方式,因为这种排列方式可以非常明显的看出包含了每一种排列方式,而对其中的排列顺序稍加修改,便可以很好的写出我们的递归程序

递归思维方式:

                 同样是排列1 2 3

第一次排序:将1 2 3 三个数分别写入第一个空

                        1 _ _ 

                        在此时先不着急将别的元素写入第一个位置列排序,而是递归调用我们的写入函数,将剩下的元素依次写入第二个位置:

                        第二次排序:

                        将每个排列后的剩下的元素依次写入第二个空

                         12 _                                             

                        将2放入第二个位置后先不着急将另一个元素放入第三个,而此时我们递归调用写入函数,将剩下的元素写入第三个位置中,

                        第三次排序:

                           123  

                        此时该次的递归调用结束,放回上一级(对13_的排序)(注意,再结束递归调用后,每次返回上一级的时候都还需要将每个元素换回之前的位置,这样下一次排列才是正确的)

                          13 _ ....同上调用    

                         2 _ _同上

                        3 _ _同上

通过以上操作便可以很好的对一组数字进行排序。(尽量表达清楚了,如果还是不懂可以私信鸭,表达能力有限)

例题及代码实现:

题解:依据每个选手说的话写出判断逻辑,后再运用全排列,对每种可能的排列进行判断即可。

void swap(char* a, char* b) //交换代码
{
	char temp = *a;
	*a = *b;
	*b = temp;
}
void order(char* rank,int start, int length)//排列函数,参数分别为:需要排列的元素数组,开始放入的位置,元素个数
{
	 if (start == length ) {
		 if ((rank[1] == 'b') + (rank[2] == 'a')==1
			 && (rank[1] == 'b') + (rank[3] == 'e')==1
			 && (rank[0] == 'c') +( rank[1] == 'd')==1 
			 && (rank[4] == 'c') +( rank[2] == 'd')==1
			 && (rank[3] == 'e')+( rank[0] == 'a')==1
			 ) //判断逻辑,只要有符合的就打印并且break
		 {
			 for (int i = 0; i < 5; i++) {
				 printf("%d名为%c\n", i + 1, rank[i]);
			 }
			 return;
		 }
		/* for (int i = 0; i < 5; i++) {//次注释为打印出每种排列
			 printf("%c", rank[i]);
		 }
		 printf("\n");
		return;*/
	}
	for (int i = start; i < length; i++) {		
		swap(&rank[start], &rank[i]);		//将每个元素放入start位置
		order(rank, start + 1, length);		//将每个元素一次放入start+1的位置上
		swap(&rank[start], &rank[i]);		//将元素换回,以便下次循环的排列
	}
}
int main() {
	char rank[5] = { 'a','b','c','d','e'};
	order(rank, 0, 5);
}

 结果展示:

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值