递归算法怎么理解,java递归算法经典实例

黄阳秋

%@ page contentType=text/html; charset=gb2312 language=java import=java.sql.* errorPage= %htmlheadtitle/titlemeta http-equiv=Content-Type content=text/html;charset=gb2312; script language=JavaScript!--function MM_goToURL() { //v3.0var i, args=MM_goToURL.arguments; document.MM_returnValue = false;for (i=0; i(args.length-1); i =2) eval(args[i] .location=' args[i 1] ');}//--/scriptlink href=css/ip.css rel=stylesheet type=text/css/headbody topmargin = 0 leftmargin = 0 marginheight = 0 marginwidth = 0 bgcolor=#FFFFFFtable border=0 cellspacing=0 cellpadding=0 height=80%trtd/td/trtr valign=toptd height=223 span id=menus/spanspan id=view/span/td/trtr valign=bottomtdnbsp;/td/tr/tablediv align=right/div/bodyscript/*** 构造树,初值为0*/function isbrother(){var is=flase;}function tree(n) {var id = new Array(bar,pad,IMG src='http://www.webjx.com/htmldata/2005-08-02/images/midnodeline.gif'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/close.gif 'border=0 align='absmiddle',IMG src='http://www.webjx.com/htmldata/2005-08-02/images/midclosedfolder.gif 'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/close.gif 'border=0 align='absmiddle',IMG src='http://www.webjx.com/htmldata/2005-08-02/images/lastnodeline.gif'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/close.gif 'border=0 align='absmiddle');if(n == 0) { // 初始化变量n = 1;i = 0;s = ;}s = table border=0 cellspacing=0 cellpadding=0 ;for(;itree_ar.length-1;i ) {var k = (n = tree_ar[i 1][0])?0:1;if(tree_ar[i][2]==false){id[2]=IMG src='http://www.webjx.com/htmldata/2005-08-02/images/lastnodeline.gif'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/close.gif 'border=0 align='absmiddle';}s = tr id=' id[k] ' value= i td id[k 2] /tdtd tree_ar[i][1] /td/tr; // // 构造节点,注意这里的自定义属性value。

作用是简化构造节点的描述,共享参数数组信息。

if(n tree_ar[i 1][0]) { // 若期望层次大于当前层次,结束本层次返回上一层次。

s = /td/tr/table;return tree_ar[i 1][0];}if(n tree_ar[i 1][0]) { // 若期望层次小于当前层次,递归进入下一层次。

s = tr style='display:none' td ;if(tree_ar[i][2]==true){ //如果有下个兄弟节点,则画兄弟节点间的连线s =background='images/line.gif' border=0 align='absmiddle';}s =/tdtd;var m = tree(tree_ar[ i][0]);s = /td/tr;if(m n) { // 当递归返回值小于当前层次期望值时,将产生连续的返回动作s = /table;return m;}}}s = /table;return s;}/scriptscript for=pad event=onclick// 分枝节点的点击响应v = this.parentElement.rows[this.rowIndex 1].style;if(v.display == 'block') {v.display = 'none';this.cells[0].innerHTML = IMG src='http://www.webjx.com/htmldata/2005-08-02/images/midclosedfolder.gif 'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/close.gif 'border=0 align='absmiddle';view.innerHTML = ;// 自行修改为参数数组定义的闭合动作}else {v.display = 'block';this.cells[0].innerHTML = IMG src='http://www.webjx.com/htmldata/2005-08-02/images/midopenedfolder.gif 'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/open.gif 'border=0 align='absmiddle';// view.innerHTML = b tree_ar[this.value][1] /b; // 自行修改为参数数组定义的展开动作}/*** 以下代码用于关闭已展开的其他分枝* 如需自行关闭展开的分枝则从这里直接返回或删去这段代码*/if(! tree_ar[this.value].type) //如该节点为首次进入,则记录所在层次信息genTreeInfo(this);var n = 1*this.value 1;for(i=n;itree_ar.length-1;i ) { // 关闭排列在当前节点之后的树if(tree_ar[i].type == pad) {tree_ar[i].obj2.style.display = 'none';tree_ar[i].obj1.cells[0].innerHTML = IMG src='http://www.webjx.com/htmldata/2005-08-02/images/midclosedfolder.gif 'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/close.gif 'border=0 align='absmiddle';}}while(tree_ar[--n][0] 1); //回溯到当前树的起点while(--n = 0) // 关闭排列在当前树的起点之前的树if(tree_ar[n].type == pad) {tree_ar[n].obj2.style.display = 'none';tree_ar[n].obj1.cells[0].innerHTML = IMG src='http://www.webjx.com/htmldata/2005-08-02/images/midclosedfolder.gif 'border=0 align='absmiddle'IMG src='http://www.webjx.com/htmldata/2005-08-02/images/open.gif 'border=0 align='absmiddle';}/** 记录层次信息,用以简化遍历树时的复杂的节点描述 **/function genTreeInfo(o) {var el = o.parentElement;for(var i=0;iel.rows.length;i ) {if(el.rows[i].id != ) {tree_ar[el.rows[i].value].type = el.rows[i].id;}if(el.rows[i].id == pad) {tree_ar[el.rows[i].value].obj1 = el.rows[i];tree_ar[el.rows[i].value].obj2 = el.rows[i 1];}}}/scriptscript for=bar event=onclick// 无分枝节点的点击响应//view.innerHTML = b tree_ar[this.value][1] /b; // // 自行修改为参数数组定义的点击动作// 自行修改为参数数组定义的点击动作/scriptscript for=bar event=onclick// 无分枝节点的点击响应//view.innerHTML = b tree_ar[this.value][1] /b; // uFFFDuFFFDuFFFDsuFFFDCuFFFDuFFFD?uFFFDQuFFFDuFFFDuFFFDuFFFD?uFFFDuFFFD?uFFFDIuFFFD_??uFFFDuFFFD/scriptscript/*** 基本参数数组,根据具体应用自行扩展* 数据可较简单的由服务器端提供* 列1:节点层次* 列2:节点标题* 列3: 有无下个兄弟节点* 其余自行扩充*/tree_ar = new Array(%FileTree tree=new FileTree();String array=tree.showFileTree(E:);%%=array%new Array(1,,false) // 为简化终止判断附加的空数据项);/*** 创建菜单 ***/menus.innerHTML =tree(0);/script/htmlimport java.io.File;public class FileTree {public FileTree() {}/**** 生成文件目录树** @param path* 目录路径* @return 返回jsp 页面所需的目录数组(JavaScript 数组)**//** 有无兄弟节点*/private boolean hasNexetBrother = false;/** 节点层次*/private int index=1;public String showFileTree(String path) {String s = ;File dir = new File(path);if (dir != null dir.isDirectory()) {String absolutePath = dir.getAbsolutePath();absolutePath = absolutePath.replaceAll(, );//对''的处理,在JSP参数传递时''和空格会出现错误absolutePath = absolutePath.replaceAll( , @); //对空格的处理 ,这时用'@'替代s = new Array( index ,'a href=fileList.jsp?path= absolutePath target=mainFrame dir.getName() /a', hasNexetBrother ), ;hasNexetBrother = false;index ;File[] dirs = dir.listFiles();java.util.List list = new java.util.ArrayList();for (int i = 0; i dirs.length; i ) {if (dirs[i].isDirectory()) {//去除文件.得到文件夹列表list.add(dirs[i]);}}for (int i = 0; i list.size(); i ) {if (i != list.size() - 1)hasNexetBrother = true;String dirpath = ((File) list.get(i)).getAbsolutePath();s = showFileTree(dirpath);//对子文件夹递归处理}index--;}return s;}}