C#,排列组合的堆生成法(Heap’s Algorithm for generating permutations)算法与源代码

1 排列组合的堆生成法

堆生成算法用于生成n个对象的所有组合。其思想是通过选择一对要交换的元素,在不干扰其他n-2元素的情况下,从先前的组合生成每个组合。

下面是生成n个给定数的所有组合的示例。

示例:

输入:1 2 3

输出:1 2 3

2 1 3

3 1 2

1 3 2

2 3 1

3 2 1

2 算法

算法生成(n-1)!前n-1个元素的排列,与其中每个元素相邻的最后一个元素。这将生成以最后一个元素结尾的所有置换。

如果n为奇数,则交换第一个和最后一个元素,如果n为偶数,则交换第i个元素(i是从0开始的计数器)和最后一个元素,并重复上述算法,直到i小于n。

在每次迭代中,算法将生成以当前最后一个元素结尾的所有组合。

3 源程序

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    public static partial class Algorithm_Gallery
    {
        public static void Heap_Permutation(ref int[] a, int size, int n)
        {
            if (size == 1)
            {
                return;
            }

            for (int i = 0; i < size; i++)
            {
                Heap_Permutation(ref a, size - 1, n);
                if (size % 2 == 1)
                {
                    int temp = a[0];
                    a[0] = a[size - 1];
                    a[size - 1] = temp;
                }
                else
                {
                    int temp = a[i];
                    a[i] = a[size - 1];
                    a[size - 1] = temp;
                }
            }
        }
    }
}
 

相关文章摘要:

摘要来源icon-default.png?t=N7T8https://cdmd.cnki.com.cn/Article/CDMD-10269-1012434174.htm

堆是最基本的数据结构之一,对堆进行枚举,可以作为堆各类算法复杂性分析的有力工具,有着重要的意义。
堆的枚举一方面是计数,另一方面是生成。计数即推导公式计算出具有某种特征的堆的总数目;生成即一个一个地产生所有的具有某类特点的堆。堆是一种重要的二叉树,在数据排序、优先级队列、最短路径和最小生成树的求解以及一些网络优化问题上都有广泛的应用。
本文先对已有的枚举算法进行研究,分析不同算法的时间复杂度和空间复杂度,这包括二叉树的枚举和最大值堆的枚举以及左倾堆的枚举,在已有的堆枚举生成算法基础上,本文主要完成了以下工作: 首先结合对堆中各子树结点数以及堆结构的研究,以提高堆枚举生成算法的空间复杂度为目的,本文提出了“基于排列”的最大值堆的枚举生成算法。即在给定数中,通过排列组合算法,生成所有的排列,对排列进行判断,选出能够成为最大值堆中序序列的排列,运用此排列构造对应的最大值堆。考虑到最大值堆结构的递归性质,本文继续将判断的过程递归化,即以排列中的最大值为分界点(最大值作为堆的根结点),递归判断左排列(排列中最大值左边的序列)和右排列(排列中最大值右边的序列),是否能够分别构成堆左子树和右子树的中序序列。递归化的判断过程则是将已有排列划分成更多、更小的排列来判断。较之以往的最大值堆生成算法,基于排列的生成算法避免了以往两个互动栈所需O(n)的存储空间。 其次,本文在已有的“单个数判断法”和“层次判断法”的基础上,提出了“至下而上”的最大值堆的枚举生成算法。即该算法通过“单个数判断法”,先生成堆中最深层次中的结点;当已经生成堆中完整的一层时,通过“层次判断法”来判断是否满足堆中的一层,如果满足,则继续生成堆中往上一个层次的结点,不满足则重新生成该层,即由深层次向低层次构造一个堆。在以往的生成堆的过程中,主要考虑的是整个堆的生成,它从根结点开始,一层层往下生成一个完整的堆,只有在生成整个堆的时候,才可以知道堆的最后一层的元素及叶子结点的值。而“至下而上”的堆的生成改进了上述的不足,在生成堆的过程中,提前知道底层结点的值。为今后堆研究过程中,对底层结点的运用提供了一个可靠的方法。相比较“基于排列”的枚举算法,本算法在空间复杂度上,增加了O(n)的存储空间。但是“至下而上”的最大值堆的枚举生成算法,采用“单个数判断法”和“层次判断法”两个基本方法减少了冗余步骤的生成。实验表明,本算法的生成时间开销相比较“基于排列”的枚举算法平均减少了80%。 本文的最后,对所有堆的枚举算法进行了总结,并且提出了对堆枚举生成算法的改进方法和展望。以上这些工作为进一步研究堆的性质提供了有力的帮助,也为今后进一步的研究奠定了基础。

4 源代码

using System;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public static partial class Algorithm_Gallery{public static void Heap_Permutation(ref int[] a, int size, int n){if (size == 1){return;}for (int i = 0; i < size; i++){Heap_Permutation(ref a, size - 1, n);if (size % 2 == 1){int temp = a[0];a[0] = a[size - 1];a[size - 1] = temp;}else{int temp = a[i];a[i] = a[size - 1];a[size - 1] = temp;}}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/735084.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ZigBee技术与实践教程(无线传感网技术第三天)

1.MAC层规范 在IEEE802系列标准中&#xff0c;OSI参考模型的数据链路层进一步划分为逻辑链路控制子层和介子访问子层两个子层。MAC子层使用物理层提供的服务实现设备之间的数据帧传输&#xff0c;而LLC在MAC 层的基础上&#xff0c;在设备之间提供面向连接和非连接的服务&…

智慧城市的新引擎:物联网技术引领城市创新与发展

目录 一、引言 二、物联网技术与智慧城市的融合 三、物联网技术在智慧城市中的应用 1、智慧交通管理 2、智慧能源管理 3、智慧环保管理 4、智慧公共服务 四、物联网技术引领城市创新与发展的价值 五、挑战与前景 六、结论 一、引言 随着科技的日新月异&#xff0c;物…

注意!!墙裂推荐几个好用的实用小工具!一定会用到的!

前言 在开发的世界里&#xff0c;面对各种挑战和问题时&#xff0c;拥有一套合适的工具箱至关重要。这不仅能提升我们的工作效率&#xff0c;还能让复杂的任务变得简单&#xff0c;甚至在解决棘手问题的同时&#xff0c;还能让我们的心情略微舒畅。众所周知&#xff0c;有用的…

STM32F103 CubeMX ADC 驱动 PS2游戏摇杆控制杆传感器模块

STM32F103 CubeMX ADC 驱动 PS2游戏摇杆控制杆传感器模块 1. 工程配置1.1 配置debug口1.2 配置时钟1.3 配置ADC1.4 配置串口1.5 配置时钟1.6 生成工程 2. 代码编写2.1 串口代码2.2 ADC读取数据的代码 1. 工程配置 1.1 配置debug口 1.2 配置时钟 1.3 配置ADC 1.4 配置串口 1.5 …

笔记本电脑使用时需要一直插电吗?笔记本正确的充电方式

随着科技的不断发展&#xff0c;笔记本电脑已经成为人们日常生活和工作中不可或缺的电子设备。而在使用笔记本电脑时&#xff0c;很多人会有一个疑问&#xff0c;那就是笔记本电脑使用时需要一直插电吗&#xff1f;本文将就此问题展开讨论。 不一定需要一直插电&#xff0c;如果…

开源组件安全风险及应对

在软件开发的过程中&#xff0c;为了提升开发效率、软件质量和稳定性&#xff0c;并降低开发成本&#xff0c;使用开源组件是开发人员的不二选择&#xff08;实际上&#xff0c;所有软件开发技术的演进都是为了能够更短时间、更低成本地构建软件&#xff09;。这里的开源组件指…

【Web开发】深度学习HTML(超详细,一篇就够了)

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Web开发】深度学习html(超详细,一篇就够了) &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 HTML1. HTML基础1.1 什么是HTML1.2 认识HTML标签1.3 HTML文件基本…

【linux进程信号】信号的产生

【Linux进程信号】信号的产生 目录 【Linux进程信号】信号的产生信号概念生活中的信号技术应用角度的信号注意信号概念用kill -l命令可以察看系统定义的信号列表信号处理常见方式概览 产生信号通过终端按键产生信号调用系统函数向进程发信号由软件条件产生信号由硬件异常产生信…

Linux 理解进程

目录 一、基本概念 二、描述进程-PCB 1、task_struct-PCB的一种 2、task_ struct内容分类 三、组织进程 四、查看进程 1、ps指令 2、top命令 3、/proc文件系统 4、在/proc文件中查看指定进程 5、进程的工作目录 五、通过系统调用获取进程标示符 1、getpid()/get…

css--浮动

一. 浮动的简介 在最初&#xff0c;浮动是用来实现文字环绕图片效果的&#xff0c;现在浮动是主流的页面布局方式之一。 二. 元素浮动后的特点 &#x1f922;脱离文档流。&#x1f60a;不管浮动前是什么元素&#xff0c;浮动后&#xff1a;默认宽与高都是被内容撑开&#xff0…

Redis基础篇:初识Redis(认识NoSQL,单机安装Redis,配置Redis自启动,Redis客户端的基本使用)

目录 1.认识NoSQL2.认识Redis3.安装Redis1.单机安装Redis2.配置redis后台启动3.设置redis开机自启 4.Redis客户端1.Redis命令行客户端2.图形化桌面客户端 1.认识NoSQL NoSQL&#xff08;Not Only SQL&#xff09;数据库是一种非关系型数据库&#xff0c;它不使用传统的关系型数…

ORACLE Linux(OEL) - Primavera P6EPPM 安装及分享

引言 继上一期发布的CentOS版环境发布之后&#xff0c;近日我制作了基于ORACLE Linux的P6虚拟机环境&#xff0c;同样里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机&#xff0c;请先与Oracle Primavera销售代表取得联系…

【Spring】Spring状态机

1.什么是状态机 (1). 什么是状态 先来解释什么是“状态”&#xff08; State &#xff09;。现实事物是有不同状态的&#xff0c;例如一个自动门&#xff0c;就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机&#xff0c;也就是被描述的事物的状态的数量是有…

Python 一步一步教你用pyglet制作汉诺塔游戏

目录 汉诺塔游戏 1. 抓取颜色 2. 绘制圆盘 3. 九层汉塔 4. 绘制塔架 5. 叠加圆盘 6. 游戏框架 汉诺塔游戏 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;是一个源于印度古老传说的益智玩具。这个传说讲述了大梵天创造世界的时候&#xff0c;他做了三根金刚…

【Leetcode每日一刷】滑动窗口:209.长度最小的子数组

一、209.长度最小的子数组 1.1&#xff1a;题目 题目链接 1.2&#xff1a;解题思路 题型&#xff1a;滑动窗口&#xff1b;时间复杂度&#xff1a;O(n) &#x1faa7; 滑动窗口本质也是双指针的一种技巧&#xff0c;特别适用于字串问题 ❗❗核心思想/ 关键&#xff1a;左右…

【笔记】原油阳谋论

文章目录 石油的属性能源属性各国石油替代 金融属性黄金石油美元 油价历史油价传导路径 石油供需格局与发展供需格局各国状况美国俄罗斯沙特 产油国困境运输 分析格局分析供需平衡分析价差分析价差概念基本面的跨区模型跨区模型下的价差逻辑 长中短三期分析长期视角——供应看投…

【笔记】全国大学生GIS应用技能大赛练习总结

该总结笔记为小组成员在练习完毕了历届题目后自我总结的结果&#xff0c;如有不足之处可以在评论区提出&#xff0c;排版较乱往谅解 绘制带空洞的面要素&#xff1a; 法一&#xff1a; 1、矢量化整个区域。2、矢量化空洞区域。3、将矢量化空洞区域进行合并&#xff08;编辑器…

Spring MVC 全局异常处理器

如果不加以异常处理&#xff0c;错误信息肯定会抛在浏览器页面上&#xff0c;这样很不友好&#xff0c;所以必须进行异常处理。 1.异常处理思路 系统的dao、service、controller出现都通过throws Exception向上抛出&#xff0c;最后由springmvc前端控制器交由异常处理器进行异…

Linux C/C++下使用Lex/Yacc构建实现DBMS(Minisql)

DBMS&#xff08;数据库管理系统&#xff09;是一种用于管理和组织数据库的软件系统。它的重要性在于提供了一种有效地存储、管理和访问大量数据的方式。本文将深入探讨如何使用C语言、Lex&#xff08;词法分析器生成器&#xff09;和Yacc&#xff08;语法分析器生成器&#xf…

Linux安装MeterSphere并结合内网穿透实现公网远程访问本地服务

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…