解决八皇后问题,递归与非递归方式两种

回溯法理解,一般形式

void Bcktrack(int t) //参数t表示当前递归深度
{
    if(t>n)Output(x); //遍历到解,则将解输出或其他处理
    else
    {
        //f(n,t)和g(n,t)表示当前节点(扩展节点)处未搜索过的子树的起始编号和中指编号
        for(int i=f(n,t);i<=g(n,t);i++)
        {
            x[t]=h(i);    //h(i)表示当前节点(扩展节点)处x[i]的第i个可选值
            if(Constarint(t)&&Bound(t)) //剪枝函数:约束函数,限界函数
                Bcktrack(t+1);
        }
    }
}

例子一,八皇后问题

// MyEightQueen.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <VECTOR>
#include <iostream>

using namespace std;

class EightQueen{
public:
    EightQueen(int n){
        nqueen = n;
        solution.resize(nqueen + 1);
        numofsolutions = 0;
    }
    void put(){
        _put(1);
    }
    int getnumofsolutions(){
        return numofsolutions;
    }
private:

    bool isplace(int n){
        for(int i=1 ; i<n ; i++){
            if(solution[i]==solution[n] || abs(n-i) == abs(solution[i] - solution[n]))
                return false;
        }
        return true;
    }
    void _put(int n){
        if(n > nqueen){    //搜索到一个符合要求的解法
            for(int i = 1;i<=nqueen;i++)
                cout<<solution[i]<<" ";
            cout<<endl;
            numofsolutions++;
        }
        else{
            for(int j = 1;j<=nqueen;j++){
                solution[n] = j;
                if(isplace(n))   //如果此处可以放置棋子,那么考虑放置下一个棋子,即_put(n+1)
                    _put(n+1);
            }
        }
    }
private:
    vector<int> solution;
    int nqueen;
    int numofsolutions;
};
int main(int argc, char* argv[])
{
    EightQueen example(8);
    example.put();
    cout<<"num of solutions "<<example.getnumofsolutions()<<endl;
    return 0;
}

例子二:01背包问题

// 01Packet.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"

int m,n=5,x[10]={0};
int w[6]={0,2,2,6,5,5},v[6]={0,6,3,5,4,6};
int c=10;
int cw=0,cv=0,bestv=0;

int f(int k)
{
    int i;
    if (k>n)             //已找到一个符合条件的解决方案
    {
        for(i=1;i<=n;i++)
            printf("%d",x[i]);
        printf("  cv = %d",cv);
        if(cv>bestv)
            bestv=cv;
        printf("\n");
    }
    else
    {
        for(int i = 0;i <= 1;i++){
            x[k] = i;                 //H[i] = {0,1}
            int tempw = i*w[k] + cw;
            int tempv = i*v[k] + cv;

            if(tempw <= c){    //限制条件
                cw = tempw;
                cv = tempv;
                f(k+1);        //进行下一层处理
                cw -= i*w[k];  //回溯之后将子路增加的和删除
                cv -= i*v[k];
            }

        }
        return k;
    }
}

int main(int argc,char * argv[]){
    f(1);
    printf("bestv is %d\n",bestv);
    return 0;
}
时间: 2024-10-10 11:19:41

解决八皇后问题,递归与非递归方式两种的相关文章

递归与非递归及其相互转换

一.什么是递归 递归是指某个函数直接或间接的调用自身.问题的求解过程就是划分成许多相同性质的子问题的求解,而小问题的求解过程可以很容易的求出,这些子问题的解就构成里原问题的解了. 二.递归的几个特点 1.递归式,就是如何将原问题划分成子问题. 2.递归出口,递归终止的条件,即最小子问题的求解,可以允许多个出口. 3.界函数,问题规模变化的函数,它保证递归的规模向出口条件靠拢 三.递归的运做机制 很明显,很多问题本身固有的性质就决定此类问题是递归定义,所以递归程序很直接算法程序结构清晰.思路明了.

二叉树之AVL树的平衡实现(递归与非递归)

这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八种情况对应平衡实现. [1] 情况1-2: 这种需要旋转的结构一般称之为LL型,需要右旋 (顺时针旋转). 我用一个图来抽象一下这两个情况,画的不好,我尽量表达吧. 此时需要对A进行平衡操作,方法为: 将A的左子树换为B的右子树. B的右子树换为A. 非递归实现的代码为: 1 void rotate

【数据结构】搜索二叉树的(递归与非递归)实现,包括:增Insert,删Remove,查Find

搜索二叉树,是二叉树一种特殊的结构. 特点: (1)每个节点都有一个关键码,并且关键码不重复. (2)左子树上的每个节点的关键码都小于根节点的关键码. (3)右子树上的每个节点的关键码都大于根节点的关键码. (4)左右子树都是搜索二叉树. 下面,为方便大家理解,我举例画一个搜索二叉树,如下: 代码见下: #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; //搜索二叉树的节点结构 template&

数据结构 递归和非递归方式实现二叉树先序、中序和后序遍历

二叉树的先序遍历顺序是根.左.右:中序遍历顺序是左.根.右:后序遍历顺序是左.右.根. 递归方式实现如下: 1 public class TreeNode { 2 private int value; 3 private TreeNode left, right; 4 5 public TreeNode(int data) { 6 value = data; 7 } 8 9 // 递归方式实现先序遍历 10 public void preorder(TreeNode treeNode) { 11

数据结构——二叉树遍历之“递归与非递归遍历”

简述 二叉树的遍历分为先序遍历.中序遍历和后序遍历.如下图所示: 递归遍历 private void bianli1(List<Integer> list, TreeNode root) { // 先序遍历 if (root == null) { return; } list.add(root.val); bianli1(list, root.left); bianli1(list, root.right); } private void bianli2(List<Integer>

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树遍历递归与非递归实现

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 二叉树遍历是二叉树中非常基础的部分,也是学习二叉树必须熟练掌握的部分,下面我们先给出二叉树三种遍历方式的定义,并通过举例来说明二叉树遍历的过程. 二叉树的遍历分为:前序遍历(也叫先序遍历).中序遍历.后序遍历.所谓前.中.后都是根据当前子树根结点相对左右孩子的位置而言,也就是说: 前序遍历:根结点在前,即:根 ----->左------->右: 中序遍历:根结点在中间,即:左------>根------>右: 后序遍历:根结点在最

树的递归与非递归遍历总结

树的递归遍历遍历很简单,非递归遍历要复杂一些,非递归先序.中序.后序遍历需要用一个辅助栈,而层次遍历则需要一个辅助队列. 树的结构: 1 public class Tree<T> { 2 private T data; 3 private Tree<T> left; 4 private Tree<T> right; 5 ... 6 } 用策略模式定义一个访问工具: 1 public interface Visitor<T> { 2 void process(

全排列(递归与非递归实现)

全排列问题在公司笔试的时候很常见,这里介绍其递归与非递归实现. 递归算法 1.算法简述 简单地说:就是第一个数分别以后面的数进行交换 E.g:E = (a , b , c),则 prem(E)= a.perm(b,c)+ b.perm(a,c)+ c.perm(a,b) 然后a.perm(b,c)= ab.perm(c)+ ac.perm(b)= abc + acb.依次递归进行. void swap(string &pszStr,int k,int m) { if(k==m) return ;