避免死循环的算法

示例:

1、Employee类

public class Employee {
	
	private String userId;
	private List<Employee> employeeList;
	
	public Employee(String userId) {
		super();
		this.userId = userId;
	}
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public List<Employee> getEmployeeList() {
		return employeeList;
	}
	public void setEmployeeList(List<Employee> employeeList) {
		this.employeeList = employeeList;
	}
}

 2、死循环代码:

public class DeadCycleTest {
	
	public static void main(String[] args) {
		Employee employee1 = new Employee("张三");
		Employee employee2 = new Employee("李四");
		Employee employee3 = new Employee("王五");
		Employee employee4 = new Employee("小六");
		
		List<Employee> employeeList1 = new ArrayList<>(); //张三的下级是李四
		employeeList1.add(employee2);
		employee1.setEmployeeList(employeeList1);
		
		List<Employee> employeeList2 = new ArrayList<>();  //李四的下级是王五
		employeeList2.add(employee3);
		employee2.setEmployeeList(employeeList2);
		
		List<Employee> employeeList3 = new ArrayList<>(); 
		employeeList3.add(employee1); //A、造成死循环,这里王五的下级又变成了张三
		employeeList3.add(employee4);
		employee3.setEmployeeList(employeeList3);
		
		//需求,找出张三的所有下级,忽略掉死循环,就是到A这里,不再往下面循环
		for(Employee childrenEmployee : employeeList1) {
			test(employee1,childrenEmployee);
		}
		
	}
	
	private static void test(Employee parentEmployee,Employee childrenEmployee) {
		System.out.println(parentEmployee.getUserId()+"的下级是"+childrenEmployee.getUserId());
		List<Employee> chilrenEmployeeIndexList = childrenEmployee.getEmployeeList();
		if(chilrenEmployeeIndexList != null) {
			for(Employee chilrenEmployeeIndex : chilrenEmployeeIndexList) {
				test(childrenEmployee,chilrenEmployeeIndex);
			}
		}
	}
}

3、死循环效果:

 

 4、跳过死循环代码 (A-1,A-2,B-1,B-2)是跳出死循环的关键步骤

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Title:
 * @Description:TODO
 * @Company:HF
 * @ClassName:DeadCycleTest.java   
 * @Author:wushigao
 * @CreateDate:2022年11月22日下午4:02:36 
 * @UpdateUser:wushigao
 * @UpdateDate:2022年11月22日 下午4:02:36 
 * @Version:1.0
 */
public class DeadCycleTest {
	
	private static Map<Employee,List<Employee>> childrenAndParentListMap;
	
	public static void main(String[] args) {
		childrenAndParentListMap = new HashMap<>();
		Employee employee1 = new Employee("张三");
		Employee employee2 = new Employee("李四");
		Employee employee3 = new Employee("王五");
		Employee employee4 = new Employee("小六");
		
		List<Employee> employeeList1 = new ArrayList<>(); //张三的下级是李四
		employeeList1.add(employee2);
		employee1.setEmployeeList(employeeList1);
		
		List<Employee> employeeList2 = new ArrayList<>();  //李四的下级是王五
		employeeList2.add(employee3);
		employee2.setEmployeeList(employeeList2);
		
		List<Employee> employeeList3 = new ArrayList<>(); 
		employeeList3.add(employee1); //A、造成死循环,这里王五的下级又变成了张三
		employeeList3.add(employee4);
		employee3.setEmployeeList(employeeList3);
		
		//需求,找出张三的所有下级,忽略掉死循环,就是到A这里,不再往下面循环
		for(Employee childrenEmployee : employeeList1) {
			test(employee1,childrenEmployee);
		}
		
	}
	
	private static void test(Employee parentEmployee,Employee childrenEmployee) {
		//A-1、判断是否死循环,看父亲是否已经作为别人的儿子,也就是父亲的父亲有哪些
		if(childrenAndParentListMap.keySet().contains(parentEmployee)) {
			List<Employee> parentEmployeeList = childrenAndParentListMap.get(parentEmployee);
			//A-2,如果父亲的父亲有自己,则存在死循环了
			if(parentEmployeeList.contains(childrenEmployee)) {
				System.out.println(parentEmployee.getUserId()+"和"+childrenEmployee.getUserId()+"死循环!");
				return;
			}
		}
		//B-1 不存在死循环,则存储我的所有父亲
		if(childrenAndParentListMap.containsKey(childrenEmployee)) {
			List<Employee> parentEmployeeList = childrenAndParentListMap.get(childrenEmployee);
			parentEmployeeList.add(childrenEmployee);
			//B-2 除了直接父亲,把父亲以上的所有所有级别都存储为自己的父亲
			getParentAllFolder(parentEmployeeList,parentEmployee);
		}else {
			List<Employee> parentEmployeeList = new ArrayList<>();
			parentEmployeeList.add(parentEmployee);
			childrenAndParentListMap.put(childrenEmployee, parentEmployeeList);
			getParentAllFolder(parentEmployeeList,parentEmployee);
		}
		System.out.println(parentEmployee.getUserId()+"的下级是"+childrenEmployee.getUserId());
		List<Employee> chilrenEmployeeIndexList = childrenEmployee.getEmployeeList();
		if(chilrenEmployeeIndexList != null) {
			for(Employee chilrenEmployeeIndex : chilrenEmployeeIndexList) {
				test(childrenEmployee,chilrenEmployeeIndex);
			}
		}
	}
	
	private static void getParentAllFolder(List<Employee> parentList,Employee parentEmployee) {
		if(childrenAndParentListMap.keySet().contains(parentEmployee)) {
			List<Employee> parentListIndex = childrenAndParentListMap.get(parentEmployee);
			if(parentListIndex.size() > 0) {
				parentList.addAll(parentListIndex);
				for(Employee employeeIndex : parentListIndex) {
					getParentAllFolder(parentList,(Employee)employeeIndex);
				}
			}
		}
	}
}

 5、效果:

 

posted @ 2022-11-22 16:33  信铁寒胜  阅读(21)  评论(0编辑  收藏  举报