排列树与子集树

  • 子集树

    子集树主要求解当前集合的所有子集,是算法中的基本思想指导。参考代码如下,以求解字符串的子集串为例子:

    

 1 /**
 2      * 子集树
 3      * @param S 字符数组
 4      * @param t 初始为0
 5      */
 6     public void ZJTree(char[] S , int t){
 7         if(t > S.length - 1){ // 叶子节点
 8             System.out.println(String.valueOf(S).replace("#",""));
 9         }else{ //非叶子结点
10             ZJTree(S,t+1);
11             char m = S[t];
12             S[t] = ‘#‘; //表示删除S[t]
13             ZJTree(S,t+1);
14             S[t] = m; //主要是在递归的过程中 S传递的是引用 不会对S现场进行保护 因此手动回复 或者上面使用 ZJTree(S.clone(),t+1);
15         }
16     }

    此代码可以结合二叉树的深度(见图)遍历进行理解,每个节点有 0(不选) 1(选择)两种方式,在实际过程中,可用合理的方式进行标记

    

    以上代码中,我们使用中间缓存 m 保存当前将要删除的节点,在递归之后进行恢复,原因是 S传递的是引用 不会对S现场进行保护 因此手动回复 或者上面使用 ZJTree(S.clone(),t+1);

  • 排列树

    排列树主要求解当前集合的所有全排列,是算法中的基本思想指导。参考代码如下,以求解字符串的全排列为例子:

 1 /**
 2      * 排列树
 3      * @param S 字符数组
 4      * @param t 初始为0
 5      */
 6     public void PLTree(char[] S , int t){
 7         if(t > S.length - 1){ // 子节点
 8             System.out.println(S);
 9         }else{ //非子结点
10             for(int i = t;i < S.length;i++){ // 多叉树遍历
11                 swap(S,t,i); //两次swap 主要保证 第一个数与任何一位进行交换一次
12                 PLTree(S,t + 1);
13                 swap(S,t,i);
14             }
15         }
16     }
17     public void swap(char[] S , int l , int r){
18         char t = S[l];
19         S[l] = S[r];
20         S[r] = t;
21     }

以上代码可以结合多叉树的深度遍历继续理解,不同的是此多叉树每一层的不同层每一个子节点的数目是递减的,使用for + 参数t 来进行控制,每层节点的字节点依次递减    

    代码中swap() 两次主要作用:for + swap 保证在S[t...length]中,将每一个节点作为头节点进行递归处理(将头节点与每一个节点进行交换),也就是:

    001: a b c(递归 b c)          b a c(递归a c)           c b a(递归b a)

原文地址:https://www.cnblogs.com/oldhands/p/11657444.html

时间: 2024-11-02 01:58:19

排列树与子集树的相关文章

两种典型的解空间树:子集树和排列树

(1)定义 子集树:所给问题是从N个元素的集合中找出满足某种性质的子集时,相应的解空间树,称为子集树.子集树通常有2^n个叶节点,遍历子集树的任何算法都需要O(2^n)的计算时间. 例如:0-1背包问题的解空间树为一棵子集树. 排列树:当所给的问题是确定N个元素满足某种性质的排列时,相应的解空间称为排列树,排列树通常有N!个叶节点,因此,遍历排列树需要N!的计算时间. 例如:旅行售货员问题的解空间树为一棵排列树. (2)回溯法遍历实现 1.搜索子集树 1 void backtrack (int

子集树和排列树

假设现在有一列数a[0],a[1], ...a[n-1] ①如果一个问题的解的长度不是固定的,并且解和元素顺序无关,即可以从中选择0个或多个,那么解空间的个数将是指数级别的,为2^n,可以用下面的子集树来表示所有的解 子集树的算法框架为: void backtrack(int t) {//表示访问到第t层,t从0开始 if (t == n) output(x); else for (int i = 0; i <= l; i++) { //表示选或不选a[t] x[t] = i; if (cons

回溯之子集树和排列树(子集和问题)

一.子集树          子集树:当所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间称为子集树.例如,那个物品的0-1背包问题所相应的解空间树就是一颗子集树.这类子集问题通常有2^n个叶节点,其节点总个数为2^(n+1)-1.遍历子集树的任何算法均需要O(2^n)的计算时间. \ void backtrack (int t) { if (t>n) output(x); else for (int i=0;i<=1;i++) { x[t]=i; if (legal(t)

回溯法 子集树和排序树

当所给问题是从n个元素的集合S中找出满足某种性质的子集时,解空间为子集树.例如:0-1背包问题 当所给问题是从n个元素的集合S中找出满足某种性质的排列时,解空间为排列树.例如:旅行售货员问题 回溯法搜索子集树算法描述为: void backtrack(int  t) { if(t>n) output(x); else for(int i=0; i<=1; i++) { x[t] = i; if(constraint(t) && bound(t)) backtrack(t+1);

看数据结构写代码(33) 树与回溯法(一) 子集树

回溯法 是 一种 在 穷举 中,裁剪 不满足 条件 的 分支,已达到 提高 效率的 方法.其基本原型 是 树的 先序遍历,从 树根 到 树叶的路径 是 问题的 一个 解. 回溯法的基本框架 =  确定 解空间 + 深度优先遍历 + 裁剪函数 + 确定结果函数 其中 解空间,分为 子集树 和 排序树. 具体 概念 详解:参考 点击打开链接  和 点击打开链接 递归算法通用 模板如下: 回溯法对解空间作深度优先搜索,因此,在一般情况下用递归方法实现回溯法. // 针对N叉树的递归回溯方法 void

子集树

最近上班上到脑袋都晕,,,突然想到要复习一下.就搞了个子集树的代码.. 其实子集树有点像暴力破解,大名鼎鼎的0-1规划中的背包问题一样.假设有N个背包,对应N个元素. 那么有:          背包                   1                   2                   3                   ...                   n                  要/不要       要/不要       要/不要    

跳跃表,字典树(单词查找树,Trie树),后缀树,KMP算法,AC 自动机相关算法原理详细汇总

第一部分:跳跃表 本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类

【经典数据结构】B树与B+树

本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树.与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作.B-tree算法减少定位记录时

K-th Number 线段树(归并树)+二分查找

K-th Number 题意:给定一个包含n个不同数的数列a1, a2, ..., an 和m个三元组表示的查询.对于每个查询(i, j, k), 输出ai, ai+1, ... ,aj的升序排列中第k个数 . 题解:用线段树,每个节点维护一个区间并且保证内部升序,对于每次查询x,返回该区间小于x的数的个数.就这样不断二分,直到找到x为止. 线段树(归并树)+二分查找 1 #include <iostream> 2 #include <cstdio> 3 #include <