zoukankan      html  css  js  c++  java
  • 数据结构之回溯算法

    借鉴:1、http://blog.csdn.net/baple/article/details/7181404

            2、http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html  回溯之模板

            3、《大话数据结构》  P240页,深度优先遍历的概念(类似于树的前序遍历)

            4、这里有个对比,非递归比递归法更能体现出回溯的过程!

    回溯题目解题一般步骤:1、找到题解的空间   2、找到约束条件  3、找到扩展的规则(下一步怎么走)

    回溯之非递归算法:

    package database;

    public class NQuee2 {

        public static void NQuee2(int arr[],int n){                         
            int k=1 ;
            arr[1]=0;                                                         // 首先对进行初始化!(确定第一步先放在哪)
            while(k>0){
                arr[k]=arr[k]+1;
                while(arr[k]<=n && !Verify(arr,k))
                    arr[k] = arr[k]+1;
                if(arr[k]<=n){                                           //这里能够看出什么时候回溯!
                    if(k==n)
                        ResultPrint(arr,n);
                    else{
                        k=k+1;
                        arr[k]=0;
                    }
                }else k=k-1;                                                              
            }
        }
        
        public static boolean Verify(int arr[],int i){                              //仅仅判断能不能放置这个皇后
            for(int k =1;k != i;k++)                                                //与前i-1行进行比较
                if(Math.abs(k-i)==Math.abs(arr[i]-arr[k]) || arr[i] == arr[k])      //具体比较的方法;
                    return false;
                return true;        
        }
        public static void ResultPrint(int arr[],int n){
            for(int a =1 ;a!=n+1 ;a++)
                System.out.print(a+","+arr[a]+";");
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int n = 4;
            int arr[] = new int[n+1];                                          //为什么是n+1? 这里要用n+1个空间,因为多一个空间是为了判断解是否超越了解空间!(a[k]>n的情况)

                                                                                         //如果超过了就回溯,如果没超过而且满足条件就继续往下
            NQuee2(arr,n);
        }

    }


    回溯之递归算法:

    package database;

    public class NQuee {

        public static boolean Verify(int arr[],int i){                                      //仅仅判断这个位置(int arr[],int i)能不能放置这个皇后
            for(int k =1;k != i;k++)                                                              //与前i-1行进行比较
                if(Math.abs(k-i)==Math.abs(arr[i]-arr[k]) || arr[i] == arr[k])      //具体比较的方法;
                    return false;
                return true;        
        }
        public static void NQuee(int arr[] , int i , int n){
            for(int j = 1;j!=n+1;j++){                               //这里是尝试着往 第i行添加皇后     
                arr[i] = j;                                                   //尝试着往(i,arr[i])添加皇后      
                                                                                //这里注意:arr[i],而i是从1开始的,那么说arr[]要开辟n+1个空间   
            if(Verify(arr, i)){                                             //利用递归开始进行回溯算法
                if(i == n)                                                   //考虑是如何进行回溯的?见PPT
                    ResultPrint(arr,n);                
                else
                    NQuee(arr, i+1, n);
            }
            }
        }
        
        public static void ResultPrint(int arr[],int n){
            for(int a =1 ;a!=n+1 ;a++)
                System.out.print(a+","+arr[a]+";");
        }
        
        public static void main(String[] args) {
            int n = 4;
            int arr[] = new int[n+1];                                          //为什么是n+1? 这里要用n+1个空间,因为多一个空间是为了判断解是否超越了解空间!(a[k]>n的情况)

                                                                                         //如果超过了就回溯,如果没超过而且满足条件就继续往下

                                                                                         //数组初始化为0
            NQuee(arr,1,n);
            
        }

    }

    后记:回溯法之模板

    1、非递归

    int a[n],i;

    初始化数组a[ ];

    i=1;

    While (i>0(有路可走)) and (未达到目标) //还未回溯到头

     { if (i=n) 搜索到一个解,输出;  //搜索到叶结点

       else                     //正在处理第i个元素

          {a[i]第一个可能的值;

           while (a[i]不满足约束条件且在搜索空间内)  

               a[i]下一个可能的值;

           if (a[i]在搜索空间内)      

                {标识占用的资源; i=i+1;}    //扩展下一个结点

           else  {清理所占的状态空间;i=i-1;}  //回溯

         }

    }

    递归框架:

    int a[n];

    try(int i)

     {   if (i>n) 输出结果;
     else

              for(j=下界 ; j<=上界; j++) //枚举i所有可能的路径
           { if ( check(j)=1)        //满足限界函数和约束条件

                   { a[i]=j;

                      ……            //其它操作

                      try(i+ 1);}

                 回溯前的清理工作(如:a[i]置空值);                     //有的要重头开始排序!

               }

     }

    态度决定行为,行为决定习惯,习惯决定性格,性格决定命运
  • 相关阅读:
    SSAS没有注册类别 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG)) 解决办法
    Javascript中暂停功能的实现
    【转】JQuery ajax json 实例
    SqlDataAdapter有关InsertCommand,UpdateCommand,DeleteCommand 实例
    绑定数组对象DataTable.Select返回值DataRow[]
    SQL SERVER 联想函数重写
    JQuery Dialog(转)
    温习C 文件操作
    轻松掌握Windows窗体间的数据交互
    反射方法调用时的一个错误:参数计数不匹配( parameter count mismatch )
  • 原文地址:https://www.cnblogs.com/neversayno/p/5204137.html
Copyright © 2011-2022 走看看