数据结构:回溯法与树的遍历

求含n个元素的集合的幂集(具体参见严蔚敏《数据结构》6.7节)

/
//回溯法求幂集(深度优先遍历解空间)

#include <iostream>
#include <vector>

using namespace std;


void GetPowerSet( const vector<int>& SrcVec, vector<int>& DstVec, int i )
{
	if ( i >= SrcVec.size() )
	{
		if ( DstVec.empty() ) cout << "空集" << endl;
		else
		{
			for( int j = 0; j < DstVec.size(); ++j ) cout << DstVec[j] << " ";
			cout << endl;
		}
	}
	else
	{
		//加入当前元素
		DstVec.push_back( SrcVec[i] );
		GetPowerSet( SrcVec, DstVec, i+1 );

		//不加入当前元素
		DstVec.pop_back();
		GetPowerSet( SrcVec, DstVec, i+1 );

	}
}


int main()
{
	vector<int> SrcVec;
	SrcVec.push_back( 1 );
	SrcVec.push_back( 2 );
	SrcVec.push_back( 3 );
	SrcVec.push_back( 4 );
	SrcVec.push_back( 5 );

	vector<int> DstVec;
	GetPowerSet( SrcVec, DstVec, 0 );

	return 0;
}


4皇后问题(具体参见严蔚敏《数据结构》6.7节)

///
//回溯法求解n皇后问题
//
#include <iostream>
#include <iomanip>

using namespace std;

#define N					8			//棋盘大小
int gChessboard[N][N];					//棋盘NxN
int gResultCount;


//约束:任何两个棋子不占据棋盘上的同一行、或者同一列,或者同一对角线
//注意:进入本函数时,在棋盘的i-1行已放置好互不攻击的i-1个棋子。
bool CheckConstraint( int i, int j )
{
	int m = 1;
	for ( int k = i-1; k >= 0; --k )
	{
		//检查与前面的行是否有同列的
		if ( gChessboard[k][j] > 0 ) return false;

		//检查与前面的行是否在一对角线上
		if ( (j-m) >= 0 && gChessboard[k][j-m] > 0 ) return false;
		if ( (j+m) < N && gChessboard[k][j+m] > 0 ) return false;
		++m;
	}
	return true;
}


//输出棋局
void OutPutChessboard()
{
	cout << left;
	for( int i = 0; i < N; ++i )
	{
		for( int j = 0; j < N; ++j )
		{
			cout << setw(2) << (( gChessboard[i][j] == 0 ) ? "0" : "x" ) << " ";
		}
		cout << endl;
	}
	cout << "---------------------------------------------" << endl;
	cout << right;
}


//对第i行进行试探性放入棋子
void Trial( int i )
{
	if ( i >= N )
	{
		//输出合法的棋盘布局
		OutPutChessboard();

		//统计解的个数
		gResultCount++;
	}
	else
	{
		for( int j = 0; j < N; ++j )
		{
			//在第i行,j列放入棋子
			gChessboard[i][j] = 1;
			if ( CheckConstraint( i, j ) ) Trial( i+1 );//当前布局合法

			//....不合法,进行剪枝(专业术语,简单理解就是不继续搜索此条线路)
			
			//移除之前放入第i行,j列棋子
			gChessboard[i][j] = 0;

		}
	}
}


int main()
{
	//回溯求解N皇后
	Trial( 0 );

	cout << N << "皇后问题----搜索到的解个数:" << gResultCount << endl;

	return 0;
}



作者:山丘儿
转载请标明出处,谢谢。原文地址: http://blog.csdn.net/s634772208/article/details/46682283

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值