当前位置:编程学习 > C#/ASP.NET >>

高分求教

谁能给出八皇后问题的递归的图形解释 --------------------编程问答-------------------- sf````jf --------------------编程问答-------------------- 不懂,没有听说过 --------------------编程问答-------------------- 八皇后? --------------------编程问答-------------------- 递归这个东西 是对堆和栈的操作
说白了就是
a,b,c是同一级别的
a1属于a,a2属于a
b1属于b,b2属于b
然后他先通过条件查出a ,然后本觉得应该查b ,但是你通过递归调用传的参数是a,这时他会继续通过a这个条件查出a1,依次类推,直到查出最后一个子节点a2为止,这时从堆栈把之前查询的一层层弹出,在由b开始继续查下去,最后查处所有节点

这东西你还是要自己加断点一点一点看,自己感觉吧 ,有时候说不太清楚。。。。 --------------------编程问答-------------------- 八皇后问题,以前听过,听好奇的在网上找了下资料,这是我找到的,我大致看了下,递归算法不难,难得是图像解释,这个是用C解释的,你参照看看吧。
八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 
高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。 
对于八皇后问题的实现,如果结合动态的图形演示,则可以使算法的描述更形象、更生动,使教学能产生良好的效果。下面是笔者用Turbo C实现的八皇后问题的图形程序,能够演示全部的92组解。八皇后问题动态图形的实现,主要应解决以下两个问题。 
(1)回溯算法的实现 
(a)为解决这个问题,我们把棋盘的横坐标定为i,纵坐标定为j,i和j的取值范围是从1到8。当某个皇后占了位置(i,j)时,在这个位置的垂直方向、水平方向和斜线方向都不能再放其它皇后了。用语句实现,可定义如下三个整型数组:a[8],b[15],c[24]。其中: 
a[j-1]=1 第j列上无皇后 
a[j-1]=0 第j列上有皇后 
b[i+j-2]=1 (i,j)的对角线(左上至右下)无皇后 
b[i+j-2]=0 (i,j)的对角线(左上至右下)有皇后 
c[i-j+7]=1 (i,j)的对角线(右上至左下)无皇后 
c[i-j+7]=0 (i,j)的对角线(右上至左下)有皇后 
(b)为第i个皇后选择位置的算法如下: 
for(j=1;j<=8;j++) /*第i个皇后在第j行*/ 
if ((i,j)位置为空)) /*即相应的三个数组的对应元素值为1*/ 
{占用位置(i,j) /*置相应的三个数组对应的元素值为0*/ 
if i<8 
为i+1个皇后选择合适的位置; 
else 输出一个解 

(2)图形存取 
在Turbo C语言中,图形的存取可用如下标准函数实现: 
size=imagesize(x1,y1,x2,y2) ;返回存储区域所需字节数。 
arrow=malloc(size);建立指定大小的动态区域位图,并设定一指针arrow。 
getimage(x1,y1,x2,y2,arrow);将指定区域位图存于一缓冲区。 
putimage(x,y,arrow,copy)将位图置于屏幕上以(x,y)左上角的区域。 
(3)程序清单如下 
#include 
#include 
#include 
#include 
char n[3]={'0','0'};/*用于记录第几组解*/ 
int a[8],b[15],c[24],i; 
int h[8]={127,177,227,277,327,377,427,477};/*每个皇后的行坐标*/ 
int l[8]={252,217,182,147,112,77,42,7}; /*每个皇后的列坐标*/ 
void *arrow; 
void try(int i) 
{int j; 
for (j=1;j<=8;j++) 
if (a[j-1]+b[i+j-2]+c[i-j+7]==3) /*如果第i列第j行为空*/ 
{a[j-1]=0;b[i+j-2]=0;c[i-j+7]=0;/*占用第i列第j行*/ 
putimage(h[i-1],l[j-1],arrow,COPY_PUT);/*显示皇后图形*/ 
delay(500);/*延时*/ 
if(i<8) try(i+1); 
else /*输出一组解*/ 
{n[1]++;if (n[1]>'9') {n[0]++;n[1]='0';} 
bar(260,300,390,340);/*显示第n组解*/ 
outtextxy(275,300,n); 
delay(3000); 

a[j-1]=1;b[i+j-2]=1;c[i-j+7]=1; 
putimage(h[i-1],l[j-1],arrow,XOR_PUT);/*消去皇后,继续寻找下一组解*/ 
delay(500); 
}} 
int main(void) 
{int gdrive=DETECT,gmode,errorcode; 
unsigned int size; 
initgraph(&gdrive,&gmode,""); 
errorcode=graphresult(); 
if (errorcode!=grOk) 
{printf("Graphics error\n");exit(1);} 
rectangle(50,5,100,40); 
rectangle(60,25,90,33); 
/* 画皇冠 */ 
line(60,28,90,28);line(60,25,55,15); 
line(55,15,68,25);line(68,25,68,10); 
line(68,10,75,25);line(75,25,82,10); 
line(82,10,82,25);line(82,25,95,15); 
line(95,15,90,25); 
size=imagesize(52,7,98,38); arrow=malloc(size); 
getimage(52,7,98,38,arrow); /* 把皇冠保存到缓冲区 */ 
clearviewport(); 
settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4); 
setusercharsize(3, 1, 1, 1); 
setfillstyle(1,4); 
for (i=0;i<=7;i++) a[i]=1; 
for (i=0;i<=14;i++) b[i]=1; 
for (i=0;i<=23;i++) c[i]=1; 
for (i=0;i<=8;i++) line(125,i*35+5,525,i*35+5); /* 画棋盘 */ 
for (i=0;i<=8;i++) line(125+i*50,5,125+i*50,285); 
try(1); /* 调用递归函数 */ 
delay(3000); 
closegraph(); 
free(arrow); 
} --------------------编程问答-------------------- 这个贴儿比较强。留名, --------------------编程问答-------------------- 说白了就是循环里面调用递归不太明白 --------------------编程问答-------------------- 没有高人指教一下吗 --------------------编程问答-------------------- zijiding --------------------编程问答-------------------- 这个东西真的要你自己去加断点 自己看才能清楚 光凭说的再清楚也不会理解的 给你段例子 是递归找出tree的根节点的  你自己去看看 这个例子很简单

C#:
-----------------------------------------------------------------------------
    #region//选择显示父节点或根节点名称
    protected void tvadd_SelectedNodeChanged(object sender, EventArgs e)
    {
        if (this.tvadd.SelectedNode.Parent == null)
        {
            this.lblroot.Text = "已经是根节点了";
        }
        else
        {
            string rootnode=this.RootNode(this.tvadd.SelectedNode);//调用递归方法
            //显示根节点
            this.lblroot.Text = "根节点是" + rootnode;
            //显示父节点
            Response.Write("<script language=javascript>alert('"+this.tvadd.SelectedNode.Text+"的父节点是:" + this.tvadd.SelectedNode.Parent.Text + "')</script>");
        }
    }
    #endregion

    #region//递归返回子节点的根节点名称
    public string RootNode(TreeNode tn)
    {
        if (tn.Parent == null)
        {
            return tn.Text;
        }
        else
        {
            return RootNode(tn.Parent);
        }
    }
    #endregion --------------------编程问答-------------------- sqlserver库设计:(直接在查询分析中运行建立库,在库中填写一些记录)
-----------------------------------------------------------------------------
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[AddNodes]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[AddNodes]
GO

CREATE TABLE [dbo].[AddNodes] (
[ChildNodeID] [int] IDENTITY (1, 1) NOT NULL ,
[ChildNodeType] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[ParentID] [int] NULL 
) ON [PRIMARY]
GO



填写样式:
---------------------------------------------------------------------------
ChildNodeID(主键 int)     ChildNodeType(varchar)    ParentID(int)
      1                          a                     <null>
      2                          b                     <null>
      3                          a1                      1
      4                          a2                      1
      5                          b1                      2 --------------------编程问答-------------------- 当然还要先在页面中拖一个treeview控件了,还要先对其进行绑定,绑定代码如下:

C#:
----------------------------------------------
protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            this.NodeBind();//页面加载时解析数据库绑定TreeNode根节点
        }
    }

    #region//数据库连接字符串
    public void conString()
    {
        string conStr = "server=.;uid=sa;pwd=;database=Demo";
        con = new SqlConnection(conStr);
    }
    #endregion

    #region//页面加载时绑定TreeNode根节点
    public void NodeBind()
    {
        this.tvadd.Nodes[0].ChildNodes.Clear();//清空TreeView中所有节点
        this.tvadd.Nodes[0].Expanded = true;//设置根节点为展开形式
        this.AddChildNode("NULL",this.tvadd.Nodes[0]);
    }
    #endregion

    #region//递归解析数据库中节点并绑定在TreeView控件上
    /// <summary>
    /// 递归解析数据库中节点并绑定在TreeView控件上
    /// </summary>
    /// <param name="sqltj">要解析库这个节点归属于哪个父节点</param>
    /// <param name="tn">要添加下一级节点的父节点</param>
    public void AddChildNode(string sqltj,TreeNode tn)
    {
        string sql = "select * from AddNodes where ParentID";//查询该父节点下还有无子节点SQL语句
        if (sqltj == "NULL")
        {
            sql += " IS NULL";//也就是说是根节点下面的第一级子节点
        }
        else
        {
            sql += "=" + sqltj;//查询sqltj下有无子节点
        }
        
        DataTable dt = this.dtDataBind(sql);
        if (dt.Rows.Count == 0)//说明此节点下无子节点
        {
            return;//退出
        }
        else
        {
            for (int i = 0; i < dt.Rows.Count; i++)//循环DataTable表中子节点记录
            {
                TreeNode tnchild = new TreeNode();//创建新的子节点
                tnchild.Text = dt.Rows[i][1].ToString();//为新建子节点的文本赋值
                tnchild.Value = dt.Rows[i][1].ToString();//为新建子节点的Value赋值
                tnchild.Expanded = true;//设置为不展开节点
                tn.ChildNodes.Add(tnchild);//添加此节点的下一级子节点
                //递归调用,一直往下直到添加完这一级下面的所有子节点为止,再转到下一个父节点,并添加所有此父节点下面的所有子节点
                //i代表DataTable表中循环记录,0代表取得这个记录的ID值,为下面继续检查这个ID下是否还有子目录
                //tnchild递归传递给下一次调用此方法,此时如果这个节点下还有子节点,它便成为父节点,对它下面的子节点进行添加
                this.AddChildNode(dt.Rows[i][0].ToString(),tnchild);
            }
        }
    }
    #endregion

    #region//绑定DataTable表
    public DataTable dtDataBind(string sql)
    {
        this.conString();
        da = new SqlDataAdapter(sql,con);
        dt = new DataTable();
        da.Fill(dt);
        return dt;
    }
    #endregion
--------------------编程问答-------------------- 帮顶!! --------------------编程问答-------------------- 其实递归并不难,你要好好看看数据结构,能用递归实现的算法,要比用循环等其他方法实线简单的多,数据结构是很好的知识,当你在编程时遇到难题能够想到用数据结构解决,说明你有了很大提高。下面是我的一个递归的例子,是找到treeview节点的非亲祖先节点(就相当于直系的祖辈)。
 //递归算出不是自己的亲祖先节点
        protected int ExceptParent(int ParentID)
        {
            int parent = -1;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (Convert.ToInt32(dt.Rows[i]["id"]) == ParentID)
                {
                    parent = Convert.ToInt32(dt.Rows[i]["Parent_ID"]);
                    dt.Rows.RemoveAt(i);
                    break;
                }
            }
            if (parent > 0)
               parent = ExceptParent(parent);
            return ParentID;
        } --------------------编程问答-------------------- 看看先 --------------------编程问答-------------------- 想请教一下大侠!a[j-1]=1   第j列上无皇后   
a[j-1]=0   第j列上有皇后   
b[i+j-2]=1   (i,j)的对角线(左上至右下)无皇后   
b[i+j-2]=0   (i,j)的对角线(左上至右下)有皇后   
c[i-j+7]=1   (i,j)的对角线(右上至左下)无皇后   
c[i-j+7]=0   (i,j)的对角线(右上至左下)有皇后   
为什么数组b与c里的元素写成i+j-2  i-j+7的形式呢?这样写的依据是什么? --------------------编程问答-------------------- 反正我是没听说过,只能听强人留言了! --------------------编程问答-------------------- 关注。 --------------------编程问答-------------------- 楼主是搞科研的,我还是绕到而行吧 --------------------编程问答-------------------- up --------------------编程问答--------------------
引用 2 楼 txgaozhao 的回复:
不懂,没有听说过

一样,没听说过
补充:.NET技术 ,  ASP.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,