全排列的递归实现与非递归实现

 全排列的递归实现
例如(a, b, c):
1>以a开头后面跟着(b, c)的所有排列
2>以b开头后面跟着(a, c)的所有排列
3>以c开头后面跟着(a, b)的所有排列
后面以此类推(递归实现)

void swap(char& a, char& b)                    //交换字符串
{
     int temp;
     temp = a;
     a = b;
     b = temp;
}

bool IsSwap(char *a, int begin, int end)               //判断是否有重复字符串
{
     for(int i=begin; i<end; i++)
     {
          if(a[i]==a[end])
               return false;
     }
     return true;
}

//递归实现
void premutations(char* a, int k, int m)
{
     int i=0;
     static iCount=1;
     if(k==m)                                   //输出字符串
     {
          cout << iCount++ << " ";
          for(i=0; i<=m; i++)
          {
               cout << a[i] << " ";
          }
          cout << endl;
     }
     else
     {
          for(i=k; i<=m; i++)
          {
               if(IsSwap(a, k, i))               //判断是否有重复字符,如果没有则交换
               {
                    swap(a[i], a[k]);
                    premutations(a, k+1, m);
                    swap(a[i], a[k]);
               }
          }
     }
}


非递归全排列算法,即按字典序排列算法
基本思想是:
1.对初始队列进行排序,找到所有排列中最小的一个排列Pmin。
2.找到刚刚好比Pmin大比其它都小的排列P(min+1)。
3.循环执行第二步,直到找到一个最大的排列,算法结束。
如排列ABCDE,这是所有排列中最小的一个排列,刚好比ABCDE大的排列是:ABCED。
算法如下:
给定已知序列P =  A1A2A3.....An
对P按字典排序,得到P的一个最小排列Pmin = A1A2A3....An ,满足Ai > A(i-1) (1 < i <= n)
从Pmin开始,找到刚好比Pmin大的一个排列P(min+1),再找到刚好比P(min+1)大的一个排列,如此重复。
1.从后向前(即从An->A1),找到第一对为升序的相邻元素,即Ai < A(i+1)。
  若找不到这样的Ai,说明已经找到最后一个全排列,可以返回了。
2.从后向前,找到第一个比Ai大的数Aj,交换Ai和Aj。
3.将排列中A(i+1)A(i+2)....An这个序列的数逆序倒置,即An.....A(i+2)A(i+1)。因为由前面第1、2可以得知,A(i+1)>=A(i+2)>=.....>=An,这为一个升序序列,应将该序列逆序倒置,所得到的新排列才刚刚好比上个排列大。
4.重复步骤1-3,直到返回。


void nonCirPermutation(char *a, int k, int m)
{
     sort(a, a+m);               //将数组中元素进行升序排序
     do
     {
          copy(a, a+m+1, ostream_iterator<char>(cout, " ")); //copy函数将数组a[0,m+1)中的元素以此在标准输出流cout上输出,每个被输出的元素后面都跟随一个空格符(" ")
          cout << endl;
     } while (next_permutation(a, a+m+1));          //a[0,m+1) 左闭右开,next_permutation只会对与前面一个不同的字符串进行全排列
}



测试代码:
int main(void)
{
	char a[] = "21232";
	cout << "全排列算法递归实现  by kate19930802" << endl;
	cout << "字符串 " <<a << " 的全排列" << endl;
	premutations(a, 0, strlen(a)-1);
	//nonCirPermutation(a, 0, strlen(a)-1);
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值