构建生成树算法----得到父节点的值

本文介绍了一种基于回溯法的生成树算法实现过程,通过递归思想构建树形结构,并根据节点值计算总值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在一个项目中接触到一个算法,类似于构建生成树算法,但是还是有点不同,首先讲一下该算法的构建所需要实现的功能,如下图所示:

 比如:要得到A的值,若是B和C的值不为空,那么A=B+C,若是B的值为空,那么就继续找父节点为B的节点信息,若D和E的值不为空,那么A=C+D+E,若是D为空,那么A的值是得到不到的,返回为空,若是D值不为空,E值为空,那么找E的孩子节点信息,若是G不为空的话,那么A=D+G-+C   本算法的大致意思就是这样,那么该如何实现呢?

再项目开发过程中,我是先考虑实现功能,在功能实现的基础上再考虑算法功能优化为题,该算法采用的是算法思想中的回溯法,首先看下该算法设计的步骤

1.构建树之前先建立一个实体类TreeModel,其中该类中包含三个参数,如下代码所示:

public class TreeModel {
		
	private Long no;
	private String scheduleid;
	private Long fatherno;
	public Long getNo() {
		return no;
	}
	public void setNo(Long no) {
		this.no = no;
	}
	public String getScheduleid() {
		return scheduleid;
	}
	public void setScheduleid(String scheduleid) {
		this.scheduleid = scheduleid;
	}
	public Long getFatherno() {
		return fatherno;
	}
	public void setFatherno(Long fatherno) {
		this.fatherno = fatherno;
	}
	public TreeModel(Long no, String scheduleid, Long fatherno) {
		super();		
		this.no = no;
		this.scheduleid = scheduleid;
		this.fatherno = fatherno;
	}
	public TreeModel() {
		super();		
	}	
}

2.第一个参数是一个节点的标识,第二个是该节点的值,第三个参数对应的是父节点的标识,对于第一个节点A,父节点我标识为0,构建生成树的具体代码如下所示:

public class TreeModelUtil {
	/**
	 * 构建树的形状,A中的id类似一个电路路由的id,父节点id值为11的代表的是第一层,
	 *下面的则是逐层遍历
	 * */		
		public String s="";
	public String forRecursion(List<TreeModel> list,long pid){
		for (int i = 0; i < list.size(); i++) {
		//	System.out.println("treemodelutil--->"+list.get(i).getNo()+"___"+list.get(i).getScheduleid()+"__"+list.get(i).getFatherno());
			long id=list.get(i).getNo();
			String scheduleid=list.get(i).getScheduleid();
			if (list.get(i).getFatherno()==pid) {	
				Long flag=isendNode(list,id);
				if (flag==1) {
					if (scheduleid!=null) {
						s+=scheduleid+"+";
					}else {
						forRecursion(list, id);
					}					
				}
				if(flag==2){
					if (scheduleid!=null) {
						s+=scheduleid+"+";
					}else {
						s+="不可测+";
					}
				}
			}
		}
		
		return s;
	}
	public Long isendNode(List<TreeModel> list,long id){
		//此处判断是不是根节点,不是根节点为1,是跟节点2
		Long flag=(long)1;
		List<Long> listFno=new ArrayList();		
		for (int i = 0; i < list.size(); i++) {
			listFno.add(list.get(i).getFatherno());			
		}
		if (listFno.contains(id)) {
			//不是根节点
			flag=(long)1;
		}else{
			//是根节点
			flag=(long)2;
		}
		return flag;
	}	

该类中包含两个方法,第一个方法是构建生成树,第二个方法是判断是不是叶子节点。

3.先写一个测试类,如下:

public class TreeModelMain {
	public void getTestResult(){
		List<TreeModel> list = new ArrayList();
		/**
		 * 构建树的形状,A中的id类似一个电路的id,父节点id值为11的代表的是第一层, 下面的则是逐层遍历
		 * treeModel中封装的是电路id,路由段对应的规则id和(再项目中是这么应用的),攥取得到的父类id
		 */

		TreeModel treeModel1 = new TreeModel((long) 11, "A", (long) 0);
		TreeModel treeModel2 = new TreeModel((long) 22, null, (long) 11);
		TreeModel treeModel3 = new TreeModel((long) 33, "C", (long) 11);
		TreeModel treeModel4 = new TreeModel((long) 44, "D", (long) 22);
		TreeModel treeModel5 = new TreeModel((long) 55, "E", (long) 22);
		TreeModel treeModel6 = new TreeModel((long) 66, "F", (long) 33);
		TreeModel treeModel7 = new TreeModel((long) 77, "G", (long) 55);
	//	TreeModel treeModel8 = new TreeModel((long) 88, "H", (long) 33);
	//	TreeModel treeModel9 = new TreeModel((long) 99, "I", (long) 33);
		list.add(treeModel1);
		list.add(treeModel2);
		list.add(treeModel3);
		list.add(treeModel4);
		list.add(treeModel5);
		list.add(treeModel6);
		list.add(treeModel7);
	//	list.add(treeModel8);
	//	list.add(treeModel9);
		TreeModelUtil tm=new TreeModelUtil();
		String ss="";
		ss=tm.forRecursion(list, 11);
		if ( ss.contains("不可测")) {
   ss="不可测";
   System.out.println("不可测");
  }else {
   System.out.println("A=" + ss.substring(0, ss.length()-1));
  }	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub	
			TreeModelMain tmmain=new TreeModelMain();			
			tmmain.getTestResult();
		
	}

}

上例的输出结果是:A=D+E+C
这是在B不可测的情况下得到的值。

若是修改D为空,哪儿就会输出不可测,得不到值的情况

本算法主要采用的是一个递归思想,通俗的话来说出了叶子节点之外,别的孩子节点始终会变成父亲,然后就这样递归下去,最后得到值,本算法中可能还存在很多的缺陷,能忘能够得到高手的指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值