全排列算法的原理和实现代码

 更新时间:2014年08月28日 10:20:01   投稿:junjie  
这篇文章主要介绍了全排列算法的原理和实现代码,全排列是将一组数按一定顺序进行排列,如果这组数有n个,那么全排列数为n!个,需要的朋友可以参考下

全排列是将一组数按一定顺序进行排列,如果这组数有n个,那么全排列数为n!个。现以{1, 2, 3, 4, 5}为例说明如何编写全排列的递归算法。

1、首先看最后两个数4, 5。 它们的全排列为4 5和5 4, 即以4开头的5的全排列和以5开头的4的全排列。

由于一个数的全排列就是其本身,从而得到以上结果。

2、再看后三个数3, 4, 5。它们的全排列为3 4 5、3 5 4、 4 3 5、 4 5 3、 5 3 4、 5 4 3 六组数。

即以3开头的和4,5的全排列的组合、以4开头的和3,5的全排列的组合和以5开头的和3,4的全排列的组合.

从而可以推断,设一组数p = {r1, r2, r3, ... ,rn}, 全排列为perm(p),pn = p - {rn}。

因此perm(p) = r1perm(p1), r2perm(p2), r3perm(p3), ... , rnperm(pn)。当n = 1时perm(p} = r1。

为了更容易理解,将整组数中的所有的数分别与第一个数交换,这样就总是在处理后n-1个数的全排列。

算法如下:

#include <stdio.h> 

int n = 0; 

void swap(int *a, int *b) 
{   
  int m;   
  m = *a;   
  *a = *b;   
  *b = m; 
} 
void perm(int list[], int k, int m) 
{   
  int i;   
  if(k > m)   
  {     
    for(i = 0; i <= m; i++)       
      printf("%d ", list[i]);     
    printf("\n");     
    n++;   
  }   
  else   
  {     
    for(i = k; i <= m; i++)     
    {       
      swap(&list[k], &list[i]);       
      perm(list, k + 1, m);       
      swap(&list[k], &list[i]);     
    }   
  } 
} 
int main() 
{   
  int list[] = {1, 2, 3, 4, 5};   
  perm(list, 0, 4);   
  printf("total:%d\n", n);   
  return 0; 
}

谁有更高效的递归和非递归算法,请回贴。

相关文章

  • getdate()函数的用法实例

    getdate()函数的用法实例

    getdate()函数的用法实例,需要的朋友可以参考一下
    2013-03-03
  • C++ std::unique_lock 用法实例详解

    C++ std::unique_lock 用法实例详解

    std::unique_lock 是 C++11 提供的一个用于管理互斥锁的类,它提供了更灵活的锁管理功能,适用于各种多线程场景,这篇文章给大家介绍了C++ std::unique_lock 用法,感兴趣的朋友跟随小编一起看看吧
    2023-09-09
  • Qt增加版本公司等信息两种方式

    Qt增加版本公司等信息两种方式

    在项目中生成exe或者动态库过程中可能需要加入公司信息、版本号、说明等等,下面这篇文章主要给大家介绍了关于Qt增加版本公司等信息的两种方式,需要的朋友可以参考下
    2024-01-01
  • C++中for auto的用法及说明

    C++中for auto的用法及说明

    这篇文章主要介绍了C++中for auto的用法及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • c++ const引用与非const引用介绍

    c++ const引用与非const引用介绍

    const引用是指向const对象的引用,可以读取ref,但不能修改所以也就有将const变量赋值给非const引用是非法的,感兴趣的朋友可以了解下,或许本文对你有所帮助
    2013-01-01
  • 详解C++的模板中typename关键字的用法

    详解C++的模板中typename关键字的用法

    在C++的Template中我们经常可以见到使用typename来定义类型名称,更加具体的我们就在接下来为大家详解C++的模板中typename关键字的用法,需要的朋友可以参考下:
    2016-06-06
  • 深入理解C/C++中的写时拷贝

    深入理解C/C++中的写时拷贝

    这篇文章主要给大家介绍了C/C++中写时拷贝的相关资料,所谓写时拷贝也就是拖延版的深拷贝,下面文章中介绍的非常清楚,需要的朋友可以参考学习,下面来一起看看吧。
    2017-03-03
  • jQuery移动页面开发中主题按钮的设计示例

    jQuery移动页面开发中主题按钮的设计示例

    这篇文章主要介绍了jQuery移动页面开发中主题按钮的设计示例,jQuery是当今最具人气的JavaScript开发类库,需要的朋友可以参考下
    2015-12-12
  • Qt中QStringList与QString的常用方法总结

    Qt中QStringList与QString的常用方法总结

    这篇文章主要为大家总结了Qt中QString 与 (QStringList | QByteArray)之间的转换,以及QString、QStringList的一些常用方法,感兴趣的可以收藏一下
    2022-12-12
  • C语言带头双向循环链表的示例代码

    C语言带头双向循环链表的示例代码

    这篇文章主要介绍了如何利用C语言实现带头双向循环链表,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-11-11

最新评论