6.7 回溯法和树的遍历

本文介绍回溯法,其实质是先序遍历一棵“状态树”的过程,树在遍历中建立。以求含n个元素的集合的幂集为例,集合每个元素有两种状态,求幂集就是先序遍历对应状态树的过程,还给出了相关算法伪码。

典型应用:求含n个元素的集合的幂集

集合A的幂集是由集合A的所有子集所组成的集合。如:A={ 1, 2, 3 },则 A 的幂集 p(A) = { {1, 2, 3} , {1, 2} , {1, 3} , {2, 3} , {1} , {2} , {3} , { } }

  • 幂集 p(A) 的每个元素是一个集合,它或是空集,或含集合A中的一个元素,或含集合A中的两个元素,或者等于集合A
    从集合A来看,它的每个元素只有两种状态:或属于幂集中的某个元素集,或不属于幂集中的元素集。

  • 求幂集p(A)的元素的过程可看成是依次对集合A中元素进行“取” 或者“弃”的过程。

  • 如下图二叉树,
    树的根结点表示幂集某个元素的初始状态(为空集)
    叶子结点表示幂集元素的终结状态(8个叶子结点表示幂集p(A)的8个元素)
    分支结点表示对集合A中前 i - 1 个元素进行取舍处理的当前状态(左分支表示,右分支表示
    综上,求幂集就是先序遍历这棵状态树的过程。
    在这里插入图片描述

  • 算法如下(伪码)

void PowerSet(int i, int n)
{
	// 求含n个元素的集合A的幂集p(A)。进入函数时已对A中前i-1个元素作了取舍处理
	// 现从第i个元素进行取弃处理。
	// 如i>n,则求得了p(A)的一个元素,并输出之
	// 初始调用: PowerSet(1, n)
	if(i > n) // n表示集合A的元素个数
	{
		输出幂集的一个元素;
	}
	else
	{/ 弃 第i个元素;
		PowerSet(i+1, n);
	}
}
  • 对上面的伪码进一步细写
void GetPowerSet(int i, List A, List &B)
{
	// 线性表A表示集合A,线性表B表示幂集p(A)的一个元素
	// 进入函数时已经对前面i-1个元素做了取舍处理
	// 第一次调用本函数时,B为空表,i=1
	if(i > ListLength(A))
	{
		// 输出当前B的值,即p(A)的一个元素
		Output(B);
	}
	else
	{
		// 获取 A 的第 i 个元素
		GetElem(A, i, x);
		// B 的当前长度
		k = ListLength(B);
		// 取 / 舍
		ListInsert(B, k+1, x); / ListDelete(B, k+1, x);
		GetPowerSet(i+1, A, B);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值