• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#算法之全排列递归算法实例讲解

C#算法之全排列递归算法实例讲解

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c#递归算法经典实例,c#排列组合算法,c#数据结构与算法,c#算法,c#算法大全等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

排列:从n个元素中任取m个元素,并按照一定的顺序进行排列,称为排列;

全排列:当n==m时,称为全排列;

比如:集合{ 1,2,3}的全排列为:

{ 1 2 3}
{ 1 3 2 }
{ 2 1 3 }
{ 2 3 1 }
{ 3 2 1 }
{ 3 1 2 }
</div>

我们可以将这个排列问题画成图形表示,即排列枚举树,比如下图为{1,2,3}的排列枚举树,此树和我们这里介绍的算法完全一致;

算法思路:

(1)n个元素的全排列=(n-1个元素的全排列)+(另一个元素作为前缀);

(2)出口:如果只有一个元素的全排列,则说明已经排完,则输出数组;

(3)不断将每个元素放作第一个元素,然后将这个元素作为前缀,并将其余元素继续全排列,等到出口,出口出去后还需要还原数组;

这里先把集合中的元素理解为不会出现重复了,那么实现的方法(C++)如下:

成员管理,互评,文件共享,事务通知
#include <iostream>
using namespace std;

int sum = 0;//记录有多少种组合

void Swap(char str[], int a, int b)
{
    char temp = str[a];
    str[a] = str[b];
    str[b] = temp;
}

void Perm(char str[], int begin, int end)
{
    if (begin == end)
    {
        for (int i = 0; i <= end; i++)
        {
            cout << str[i];
        }
        cout << endl;
        sum++;
        return;
    }
    else
    {
        for (int j = begin; j <= end; j++)
        {
            Swap(str, begin, j);
            Perm(str, begin + 1, end);
            Swap(str, j, begin);
        }
    }
}

int main()
{
    int n;
    char c[16];
    char tmp;


    cin >> n;
    tmp = getchar();    // 接受回车
    if (1 <= n && n <= 15) {
        for (int i = 0; i < n; i++) {
            c[i] = getchar();
        }
        Perm(c, 0, n - 1);
    }
    cout << sum;
    cout << endl;
    return 0;
}
</div>

实现后效果如下图:

有重复元素的排列问题

然后现在的题目要求是排列中的元素是包含相同元素的,给定n以及待排的n个可能重复的元素。计算输出n个元素的所有不同排列,因此上面那个算法显然还是不够好,因为相同的元素都当成不同的元素,因此有了重复的排列在里面

去掉重复符号的全排列:在交换之前可以先判断两个符号是否相同,不相同才交换,这个时候需要一个判断符号是否相同的函数。也就是下面的IsSwap();

对122,第一个数1与第二个数2交换得到212,然后考虑第一个数1与第三个数2交换,此时由于第三个数等于第二个数,所以第一个数不再与第三个数交换。再考虑212,它的第二个数与第三个数交换可以得到解决221。

去掉重复的规则:去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。

#include <iostream>
using namespace std;

int sum=0;//记录有多少种组合

void Swap(char str[], int a, int b)
{
    char temp = str[a];
    str[a] = str[b];
    str[b] = temp;
}

bool IsSwap(char *pchar, int nBegin, int nEnd)
{
    for (int i = nBegin; i < nEnd; i++)
        if (pchar[i] == pchar[nEnd])
            return false;
    return true;
}

void Perm(char str[], int begin, int end)
{
    if (begin==end)
    {
        for (int i = 0; i <= end; i++)
        {
            cout << str[i];
        }
        cout << endl;
        sum++;
        return;
    }
    else
    {
        for (int j = begin; j <= end; j++)
        {
            if (IsSwap(str, begin, j))
            {
                Swap(str, begin, j);
                Perm(str, begin + 1, end);
                Swap(str, j, begin);
            }
        }
    }
}

int main()
{
    int n;
    char c[16];
    char tmp;


    cin >> n;
    tmp = getchar();    // 接受回车
    if (1 <= n && n <= 15) {
        for (int i = 0; i < n; i++) {
            c[i] = getchar();
        }
        Perm(c, 0, n - 1);
    }
    cout << sum;
    cout << endl;
    return 0;
}
</div>

非递归的实现

实现思路:

要考虑全排列的非递归实现,先来考虑如何计算字符串的下一个排列。如"1234"的下一个排列就是"1243"。只要对字符串反复求出下一个排列,全排列的也就迎刃而解了。

如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"、"52"都是非递增的,"2

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#递归算法寻找数组中第K大的数
  • C#用递归算法解决经典背包问题
  • C#快速排序算法实例分析
  • C#二分查找算法实例分析
  • C#中尾递归的使用、优化及编译器优化
  • C#插入法排序算法实例分析
  • C#算法之全排列递归算法实例讲解
  • C#实现排列组合算法完整实例
  • c# 二分查找算法
  • C#计算两个文件的相对目录算法的实例代码

相关文章

  • 2017-05-28详解C#中的string与String
  • 2017-05-28C#使用自定义算法对数组进行反转操作的方法
  • 2017-05-28C#实现简单播放mp3的方法
  • 2017-05-28C#实现HSL颜色值转换为RGB的方法
  • 2017-05-28C++调用C#的DLL程序实现方法
  • 2017-05-28c#根据文件类型获取相关类型图标的方法代码
  • 2017-05-28C#列表框、复选列表框、组合框的用法实例
  • 2017-05-28c#数据绑定之linq使用示例
  • 2017-05-28c#删除指定文件夹中今天之前的文件
  • 2017-05-28C#实现两个richtextbox控件滚动条同步滚动的简单方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#实现向指定文本文件添加内容的方法
    • .net实现序列化与反序列化实例解析
    • Url相对路径的问题总结
    • WPF委托的运用,多线程 自定义事件
    • 基于Silverlight打印的使用详解,是否为微软的Bug问题
    • WinForm特效之桌面上的遮罩层实现方法
    • WinForm窗体调用WCF服务窗体卡死问题
    • C#程序优化-有效减少CPU占用率
    • C#程序中session的基本设置示例及清除session的方法
    • c#闭包使用方法示例

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有