java 递归层级拼接_使用递归方法拼接层级树
遞歸算法這個是非常常見的一個算法,也是大多數(shù)人都會用的,因?yàn)樗銐蚝唵?#xff0c;通俗易懂!在遍歷城市,樹等大腦里反應(yīng)出來的第一方法大多就屬于這個了
遞歸容易使用,但是也容易用壞,我想"內(nèi)存溢出"這個估計(jì)是每個人用遞歸都會碰到的bug,我為什么還是要寫這方面的知識呢,那是因?yàn)槲恼碌淖詈笪矣幸粋€問題要問
首先我先展示我之前寫的一段遞歸拼接層級樹的代碼:
private string ParentColumns(List columns, intid)
{using(msdb)
{var parents = columns.Where(p => p.parentid ==id).ToList();
StringBuilder sb= newStringBuilder();if (parents.Count > 0)
{
parents.ForEach(item=>{
sb.AppendFormat("
{0}{1}{2} ", item.cl_id, item.cl_px, item.cl_name);sb.Append(ChildColumns(columns, item.cl_id,2));
});//釋放內(nèi)存
parents = null;
}returnsb.ToString();
}
}
private string ChildColumns(List columns, int cl_id, intsub)
{var childs = columns.Where(p => p.parentid ==cl_id).ToList();
StringBuilder sb= newStringBuilder();if (childs.Count > 0)
{string substag = "";for (int i = 0; i < sub; i++)
{
substag+= "—";
}
childs.ForEach(item=>{
sb.AppendFormat("
{0}{1}{3}{2} ", item.cl_id, item.cl_px, item.cl_name, substag);sb.Append(ChildColumns(columns, item.cl_id,2 *sub));
});
childs= null;
}returnsb.ToString();
}
這代碼是我修復(fù)過的,之前報內(nèi)存溢出的代碼我就不貼了,無非就是我引用了靜態(tài)變量list以及StringBuilder類,所以遞歸的時候,內(nèi)存得不到有效釋放,最后就瀑黃頁了。
那么這個bug的本質(zhì)我說一下:因?yàn)榫€程在運(yùn)行函數(shù),都會分配一定的內(nèi)存(棧空間)給它,如方法的參數(shù),變量,返回值等!而這個方法又在不斷的調(diào)用自身,所以深度大了,其內(nèi)存又得不到釋放,就超出異常了!所以我這里用靜態(tài)變量就顯得“助紂為虐”了
那么,問題就來了,如果根據(jù)老趙的尾遞歸與Continuation一問中的描述,那我也可以改造成堆內(nèi)存不造成影響的“尾遞歸”形式,我只要用accStr來記錄上一次累加的字符串當(dāng)作參數(shù)傳遞,于是就有了下面這段異常難看的代碼
private string ChildColumnsRecursively(List columns, int cl_id, int sub,stringaccStr)
{var childs = columns.Where(p => p.parentid == cl_id).Select(p => new { id = p.cl_id, oid = p.cl_px, name =p.cl_name }).ToList();
StringBuilder sb= newStringBuilder();if (childs.Count > 0)
{string substag = "";for (int i = 0; i < sub; i++)
{
substag+= "—";
}
childs.ForEach(item=>{
sb.AppendFormat("
{0}{1}{3}{2} ", item.id, item.oid, item.name, substag);accStr+= ChildColumnsRecursively(columns, item.id, 2 *sub, sb.ToString());
});
childs= null;
sb.Append(accStr);
}returnsb.ToString();
}
這怎么看怎么不是尾遞歸,連“偽遞歸”都談不上
我心中的改造形式應(yīng)該是像下面這樣的偽代碼:
public string ChildColumnsRecursively(List columns,int id,stringaccStr){
...Logic Code
accStr=values;returnChildColumnsRecursively(columns,pid,accStr);
}
看老趙的博客,感覺看懂了,但是我想用到我這個案例上,卻又感覺差點(diǎn)東西,不知道那方面還沒理解到位...先擱這吧,以后再慢慢想解決方案
總結(jié)
以上是生活随笔為你收集整理的java 递归层级拼接_使用递归方法拼接层级树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机网络项目实训教程课后答案,计算机网
- 下一篇: Spring 钩子之BeanFactor