遞歸調用算法

      遞歸調用是程序設計中一個非常重要的方法。此法簡單直觀,結構清晰,程序易讀,給我們編制程序和調試程序帶來很大的方面,但計算機的執行過程比較複雜,時空性能相對較差。這裏從一個分類查詢開始說起。要求根據一張產品表,裏面有產品的信息,還有產品編碼,產品的父級編碼,產品是否選中(邏輯刪除)。這裏是通過一個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方法中,速度是不是就會提高很多呢?但是這樣的話,我們所要求的功能是不是還能完好的實現呢?答案就是速度會提高,功能會打折扣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章