求含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;
}




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




作者:山丘儿