点点滴滴

一直在努力,从未放弃过

递归调用算法

      递归调用是程序设计中一个非常重要的方法。此法简单直观,结构清晰,程序易读,给我们编制程序和调试程序带来很大的方面,但计算机的执行过程比较复杂,时空性能相对较差。这里从一个分类查询开始说起。要求根据一张产品表,里面有产品的信息,还有产品编码,产品的父级编码,产品是否选中(逻辑删除)。这里是通过一个TreeView来实现的,选择父节点就会选中相应的子节点,然后点击确定,就表示添加此产品;如果只选择子节点,那父节点不会自动选中,也可以添加产品信息。这里要实现的分类查询就是,只要选中子节点,那么查找后,不管有没有选中父节点,父节点都会相应的出现,并加以颜色区分。

 

 

由上图可以看出,不管煤油有没有选中,在分类查询里如果其子节点被选中了,它就会显示出来。

实现过程如下:

首先,通过查找先找出所有相应的选中产品来,并放到DataTable中。

string strSql = "select 产品编码,产品父级编码,其他信息 from 产品表 where 标识选中 = 1";

DataTable dt = GetDataTable(strSql);

然后调用递归方法,找到子节点所有的父节点;大致程序如下:

            foreach(DataRow dr in dt.Rows)
            {
                strBm += getSupId(dr["bm"].ToString()) + ",";
            }

        /// <summary>
        /// 获得父级编码
        /// </summary>
        /// <param name="strSubId">子节点编码</param>
        private string getSupId(string strSubId)
        {
            string strSql = "select 产品父级编码 from 产品表 where 产品编码 = " + strSubId+ "";
            DataTable dt = GetDataTable(strSql);

            //如果父级节点为空,它就是父级节点,返回它的编码;否则的话,传入它的编码作为父级节点继续查找
            if (dt.Rows[0][0].ToString() == "")
            {
                return strSubId;
            }
            else
            {
                //递归调用
                return getSupId(dt.Rows[0][0].ToString());
            }
        }

其次,当找到所有的父节点后,再进行查找,找相应的子节点,因为在分类查询中只有二级结构,即不管树结构中分的几级,而在分类查找中只要求两级。

         strSql = "select 产品编码,产品父级编码,其他信息 from 产品表 where 产品编码 in(" + strBM + ")";

         DataTable dt = GetDataTable(strSql);

         DataTable dtNew = null;

         foreach(DataRow dr in dt.Rows)

        {

                     dtNew.Rows.Add(dr.ItemArray);

                    //获得子集编码
                    getSubId(dr[产品编码].ToString(),ref strSubId);

                   //

                    strSql = "select 产品编码,产品父级编码,其他信息 from 产品表 where 标识选中 = 1 and 产品编码 in(" + strSubId+ ")";

                    //添加新DataTable中,此DataTable即为最中所要实现的DataTable

                      dtNew.GetDataTable(strSql);

        }

        /// <summary>
        /// 获得子级编码
        /// </summary>
        /// <param name="strSupId">父节点</param>
        /// <param name="strSubId">子节点</param>
        private void getSubId(string strSupId,ref string strSubId)
        {
            string strSql = "select 产品编码 from 产品表 where 产品父级编码 = " + strSupId + "";
            DataTable dt = GetDataTable(strSql);
            foreach(DataRow dr in dt.Rows)
            {
                if(dr[0].ToString() != "")
                {
                    strSubId += dr[0].ToString() + ",";
                    //递归调用
                    getSubId(dr[0].ToString(),ref strSubId);
                }
            }

        }

       至此差不多实现了所需要的功能。但是执行速度确实慢了下来。除了使用递归算法使速度降下来的原因外,还有对父节点查找子节点getSubId方法的过程中,没有过滤掉没有标识的产品,而是在新添加到DataTable的过程中过滤掉的,这样的话,可能一个产品会有很多个子节点,从而使速度降了下来。如果将过滤的地方改到getSubId方法中,速度是不是就会提高很多呢?但是这样的话,我们所要求的功能是不是还能完好的实现呢?答案就是速度会提高,功能会打折扣。

阅读更多
个人分类: 算法研究分析
想对作者说点什么? 我来说一句

八数码难题 C++编程

2011年06月07日 370KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭