【算法】——排列树

有这样一个问题,比如说,让我们去求数列br={1,2,3}的所有子集。我们知道它的真子集有{1,2,3}、{1,2}、{1,3}、{2,3}、{1}、{2}、{3}、空集。一共八个。那我们怎么通过代码的方式实现它呢?
首先,我们来分析这样一个程序,如下:

int fun(int i, int n)
{
	if (i >= n)
	{
	}
	else
	{
		fun(++i, n);//一般不用后置加加,会无穷递归,栈溢出
		fun(++i, n);
	}
}
int main()
{
	fun(0, 3);
}

如果我们把它与树的结构来展现,他会是什么样子呢?用层次分析法分析,如下图:
在这里插入图片描述
由上图我们可知,我们可以利用递归的方式来完成左右子树相关值的创建。那就进入正题,怎么求数列的一个子集呢。仔细观察这些子集,我们可以发现用数组来存放这些子集,数值与下标位置相对应,再用1表示有数字,0表示没有数字,展现结果如下:
在这里插入图片描述
再将此数组对应到树形结构上,左子树表示1,右子树表示0,就可以完全的表示出子集了。
在这里插入图片描述
由此,采用递归的方式我们可以写出代码如下:

void fun (int* ar, int* br, int i,int n)
{
	if (i >= n)
	{
		for (int j = 0; j < n; ++j)
		{
			if (br[j])
			{
				cout << ar[j] << "";
			}
		}
		cout << endl;
	}
	else
	{
		br[i] = 1;
		fun(ar, br, i + 1, n);//左孩子
		br[i] = 0;
		fun(ar, br, i + 1, n);
	}
}
int main()
{
	int ar[] = { 1,2,3 };
	int br[] = { 0,0,0 };
	fun(ar, br, 0, 3);
	return 0;
}

当到达最后一层i>=n的时候,就将排列树打印出来。之前都在依次按照左0右1的方式创建树。

发布了62 篇原创文章 · 获赞 7 · 访问量 2561

猜你喜欢

转载自blog.csdn.net/qq_43412060/article/details/104713582