目录
零、递归新三要素
1.入参是可递归的(例如)
public class Person
{
//省略其他字段
public List<Person> Children { set; get; }
}
2.递归遍历父节点下的子节点
3.维护返回值,即满足条件要返回、最后结果要返回。(注意:1.引用类型可直接修改其属性或字段无需返回值。2.在递归遍历引用类型属性时,需做判空处理,以防止空引用异常。)
一、根据ID求后代
using System.Text.Json;
using System.Text.Encodings.Web;
class MainClass
{
static Person root = new Person(0, "全体人类")
{
Spring = new List<Person>
{
new Person(1, "苏家")
{
Spring = new List<Person>
{
new Person(3, "苏一"),
new Person(4, "苏二"),
new Person(5, "苏三")
{
Spring = new List<Person>
{
new Person(6, "苏三仔")
{
Spring = new List<Person>
{
new Person(7, "苏三仔仔")
}
},
}
},
new Person(8, "苏三妹")
}
},
new Person(2, "李家")
{
Spring = new List<Person>
{
new Person(9, "李一"),
new Person(10, "李二")
{
Spring = new List<Person>
{
new Person(11, "李二仔")
}
}
}
}
}
};
/// <summary>
/// 递归:第一个参数是查找指定ID,第二个参数是传入需要查找的实体
/// </summary>
/// <param name="id"></param>
/// <param name="tree"></param>
/// <returns>结果:输出指定ID的个人信息及其个人的所有后代,否则返回null。</returns>
public static Person FindTree(int id, Person tree)
{
if (tree.Id == id)//1.如果实体匹配则返回实体,跳到第三步
{
return tree;
}
if (tree.Spring != null)//2.如果实体有子节点,遍历子节点递归查找
{
foreach (var item in tree.Spring)
{
var foundTree = FindTree(id, item);
if (foundTree != null)//3.找到了则中止递归
{
return foundTree;
}
}
}
return null;//4.都找不到则返回空
}
static void Main(string[] args)
{
//1.打印出这棵树的结构
string json = root.ToJson();
//Console.WriteLine(json);
//2.递归:第一个参数是查找指定ID,第二个参数是传入需要查找的实体
//结果:输出指定ID的个人信息及其个人的所有后代
//测试: 0 4 5 100
var result_tree = FindTree(5, root);
//3.打印输出
if (result_tree!=null)
{
string json2 = result_tree.ToJson();
Console.WriteLine(json2);
}
}
}
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public List<Person> Spring { get; set; }
public Person(int id, string name)
{
Id = id;
Name = name;
Spring = new List<Person>();
}
public string ToJson()
{
var options = new JsonSerializerOptions
{
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
return JsonSerializer.Serialize(this, options);
}
}
二、加一个父节点
using System.Collections.Immutable;
using System.Text.Encodings.Web;
using System.Text.Json;
class MainClass
{
static Person root = new Person(0, "全体人类")
{
Spring = new List<Person>
{
new Person(1, "苏家")
{
Spring = new List<Person>
{
new Person(3, "苏一"),
new Person(4, "苏二"),
new Person(5, "苏三")
{
Spring = new List<Person>
{
new Person(6, "苏三仔")
{
Spring = new List<Person>
{
new Person(7, "苏三仔仔")
}
},
new Person(8, "苏三妹")
}
}
}
},
new Person(2, "李家")
{
Spring = new List<Person>
{
new Person(9, "李一"),
new Person(10, "李二")
{
Spring = new List<Person>
{
new Person(11, "李二仔")
}
}
}
}
}
};
static void Main(string[] args)
{
//1.打印出这棵树的结构
string json = root.ToJson();
//Console.WriteLine(json);
//2.添加父节点,本质将原结果添加到父节点的Spring中
Person newTree = new Person(1000,"全体智慧生物");
newTree.Spring.Add(root);
//3.打印结果
string json2 = newTree.ToJson();
Console.WriteLine(json2);
}
}
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public List<Person> Spring { get; set; }
public Person(int id, string name)
{
Id = id;
Name = name;
Spring = new List<Person>();
}
public string ToJson()
{
var options = new JsonSerializerOptions
{
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
return JsonSerializer.Serialize(this, options);
}
}
三、生成一个递归树
// 从列表中找到没有父节点的元素作为树的根节点,注意list是查库得到的List<ProManDayAnalysis>
ProManDayAnalysis model = list.FirstOrDefault(w => string.IsNullOrWhiteSpace(w.ParentAmoeba));
// 递归生成树,第一个参数是整个列表,第二个参数是根节点实体
BindTree(list, model);
private void BindTree(IList<ProManDayAnalysis> dateList, ProManDayAnalysis parentItem)
{
// 找到当前节点的子节点集合
var subItems = dateList.Where(w => w.ParentAmoeba == parentItem.AmoebaCode).ToList();
if (subItems.Count != 0)//如果找到子节点
{
parentItem.Children = new List<ProManDayAnalysis>();
parentItem.Children.AddRange(subItems);// 给父节点添加孩子
foreach (var subItem in subItems)//遍历递归父节点的孩子,执行一样的操作
{
BindTree(dateList, subItem);//递归,自己调用自己
}
}
}