DFS回溯遍历

    以前想做DFS,不知道回溯怎么用代码实现,现在发现很简单,用回溯的递归就能搞定。 PKU ACM 3140,4107,1655,3099都是类似的例子。

    好多问题都可能归结成当前子树的规模,DFS,就是对某一个节点的所有没有访问的子节点一个个访问,最后归结起来就能返回。

    帖一些回溯的代码:下面的代码解决了三个问题:1:n皇后,2找出一个集合中所有满足某个条件的子集,3显示一个集合的所有子集。 注意变量数组的空间只需要一个就够了,因为是递归调用。

#include <iostream>
#include <cmath>
using namespace std;

int Num;
bool Place (int k, int i, int *x)
{
 for(int j=0;j<k;j++)
     if( (x[j]==i) || ( abs( x[j]-i)==abs(j-k)  ) ) return false;
 return true;
}

void NQueens(int k, int n, int *x)
{
 for(int i=0; i<n;i++)
 {
  if( Place(k,i,x))  //»ØËÝ·¨£¬ÀûÓóÌÐò¾Íд³öËùÓпÉÄÜÐÔ£¬ÓÉÓÚÊǵ¥Ị̈߳¬ËùÒÔ»áÖ´ÐÐÍêÒ»¸öÔÙÖ´ÐÐÏÂÒ»¸ö£¬ËùÒÔ²»ÓÃ×Ô¼ºÐ´³ö»ØËÝ£¬ÎÒÒÔǰµ±³ÉÊ÷дÁË£¬¸´ÔÓµÄÌ«¶à
  { //²»Ðеϰ£¬¾Í·ÅÆúÁËÒ»Ñù
   x[k] = i;
   if( k== n-1){
    for(int m=0;m<n;m++)
         cout << x[m]<<" ";
    cout<<endl;
    Num++;
   }
   else NQueens(k+1,n,x);
  }
 }
}
void NQueens(int n, int *x)
{
 Num = 0;
    NQueens(0,n,x);
 cout<<Num<<endl;
}


int Get(int s, int wi,int D)
{
     if( s + wi > D)
   return 1;
  else if( s + wi == D )
   return 0;
  return   -1;

}

void Sum(int k, int n, int *x,int *out, int kk,int D, int s)
{ // ´ÓÔ­Êý×éµÚk¸ö¿ªÊ¼¼ÌÐøËÑË÷£¬ Ô­Êý×én£¬*x
 //  *out kk  ½á¹ûºÍ½á¹û½«Òª±£´æµÄϱê
 // Ä¿±ê ºÍ ÏÖÔÚ״̬
 for(int i=k; i<n;i++)  // »ØËÝ·¨Ð§ÂÊÈçºÎ£¿
 {  
  int tmp = Get( s, x[i],D);
        if( tmp == 0 ) //ÏÔʾ³öÀ´
  {  
   out[kk] = x[i];
   for(int j=0;j<=kk;j++)
    cout<<out[j]<<" ";
   cout<<endl;
  }
  else if( tmp ==-1)
  {
            out[kk] = x[i];
   if( i<n-1)
      Sum(i+1,n,x,out,kk+1,D,s+x[i]); //Éî¶ÈÓÅÏÈ
  }
  else if( tmp ==1)  //²»´¦Àí£¬Ï൱ÓÚ¼ôÈ¥ÁËÊ÷µÄÒ»¸öÖ§
  {
  }
 }
}

void OnPaint(int k, char * out)
{
 for(int i=0;i<=k;i++)
  cout<<out[i]<<" ";
 cout<<endl;
}

void Show(int p, int n, char *d, char *out,int k)
{
 for(int i=p;i<n;i++)
 {
         out[k] = d[i];  OnPaint(k,out);
   Show( i+1,n,d,out,k+1);
 }
}
void ShowAllChildSet(int n, char * d)
{
 char *out = new char[n];
    Show(0,n,d,out,0);
 delete [] out;

}
int main()
{  
/* int n=10;
 int *x =new int[n];
 NQueens( n,x);
*/
/* int n =5;
 int W[10] = {7,24,11,13,7};
    int *out = new int[n];
    Sum(0, n, W,out,0,31,0);
 */
 const int n=4;
 char c[n] = {'a','b','c','d'};
 char *d = &c[0];//{'a','b'};
 ShowAllChildSet(n,d);

 return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值