DFS/01 - 数的全排列【深度优先搜索】

题目描述

数如一个数 n, 输出 1~n 的全排列。

如输入

3

输出:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

题解

基本框架:

// DFS/01-1
#include <iostream>
using namespace std;

int n;
int aNum[20] = {0}; // aNum 存储排列之后的数

void dfs(int step) // step 表示已经填入 aNum 的数字个数
{
	// 在这插入主要代码
}

int main()
{
	cin >> n;
	dfs(0); //0 表示没有填入任何数

	return 0;
}

把 dfs() 加上一个循环

void dfs(int step) // step 表示已经填入 aNum 的数字个数
{
	// 循环填数,这里 for 循环得从 1 开始
	for (size_t i = 1; i <= n; i++) // 这里 size_t 和 int 的区别不大
	{
		aNum[step] = i; // 把数字填入列表中
		dfs(step + 1); // 递归,对下一个数进行填写,step 要加一
	}
}

还要再加一个判断,防止重复填写数字。

添加一个 book 布尔类型数组,book 的下标表示一个数字

如果 book[i] 为 true 说明数字 i 没有被填写,如果 book[i] 为 false 说明数字 i 已经被填写

要先在主函数初始一下 book

int main()
{
	cin >> n;
        
        // 初始化 book
	for (size_t i = 0; i < 20; i++)
	{
		book[i] = true;
	}

	dfs(0); //0 表示没有填入任何数

	return 0;
}

再在 dfs() 中写代码

int book[20] = { true }; // 新建数组 book

void dfs(int step) // step 表示已经填入 aNum 的数字个数
{
	// 循环填数,这里 for 循环得从 1 开始
	for (size_t i = 1; i <= n; i++) // 这里 size_t 和 int 的区别不大
	{
		if (book[i]) // 判断此数字有没有被填写
		{
			aNum[step] = i; // 把数字填入列表中
			book[i] = false; // 此数字已经被填写
			dfs(step + 1); // 递归,对下一个数进行填写,step 要加一
			book[i] = true; // 递归结束后,收回此数字。
		}
	}
}

最后再加上一个边缘检测

如果所有数字已经填完,则表明已经排好一个排列,所以最后要输出排列

直接把完整代码发上来:

// DFS/01-1
#include <iostream>
using namespace std;

int n;
int aNum[20] = {0}; // aNum 存储排列之后的数
int book[20];
void dfs(int step) // step 表示已经填入 aNum 的数字个数
{
	if (step == n)
	{
		// 输出
		for (size_t i = 0; i < n; i++)
			cout << aNum[i] << " ";
		cout << "\n";

		return; // 这个必须要
	}

	// 循环填数,这里 for 循环得从 1 开始
	for (size_t i = 1; i <= n; i++) // 这里 size_t 和 int 的区别不大
	{
		if (book[i]) // 判断此数字有没有被填写
		{
			aNum[step] = i; // 把数字填入列表中
			book[i] = false; // 此数字已经被填写
			dfs(step + 1); // 递归,对下一个数进行填写,step 要加一
			book[i] = true; // 递归结束后,收回此数字。
		}
	}
}

int main()
{
	cin >> n;

	for (size_t i = 0; i < 20; i++)
	{
		book[i] = true;
	}

	dfs(0); //0 表示没有填入任何数

	return 0;
}
posted @ 2021-02-28 12:17  TDesertGFI  阅读(86)  评论(0)    收藏  举报