用递归,非递归(foreach)加载TreeView节点
由于表中的数据有点多用递归的方法慢在网上搜非递归的方法没找到,所以自己动手写了这些方法。希望有需要的人用的到。
这个例了是个winform程序,把地区表里的省、市、区数据加载到TreeView。
分别有递归、foreach、for,三个方法。用for的方法有一步还没想出该怎样搞。
表对应的实体是 TbBA_DistrictClassModel 代码如下
View Code
1 public class TbBA_DistrictClassModel 2 { 3 /// <summary> 4 /// 地区名 5 /// </summary> 6 public string iName; 7 8 /// <summary> 9 /// 节点 10 /// </summary> 11 public string iCode; 12 13 /// <summary> 14 ///父节点 15 /// </summary> 16 public string Parent 17 { 18 get { return SetParent(); } 19 // set { parent = value; } 20 } 21 22 string SetParent() 23 { 24 string per = null; 25 int len = iCode.Length; 26 if (len > 4) 27 { 28 per = iCode.Substring(0, 4); 29 } 30 else 31 if (len > 2) 32 { 33 per = iCode.Substring(0, 2); 34 } 35 return per; 36 } 37 }
public class TbBA_DistrictClassModel { /// <summary> /// 地区名 /// </summary> public string iName; /// <summary> /// 节点 /// </summary> public string iCode; /// <summary> ///父节点 /// </summary> public string Parent { get { return SetParent(); } // set { parent = value; } } string SetParent() { string per = null; int len = iCode.Length; if (len > 4) { per = iCode.Substring(0, 4); } else if (len > 2) { per = iCode.Substring(0, 2); } return per; } }
UI层的代码如下:
public partial class frmAddress : Form { public frmAddress() { InitializeComponent(); } private void frmAddress_Load(object sender, EventArgs e) { Load_tVAddress(); } private void Load_tVAddress() { List<Model.TbBA_DistrictClassModel> list = new List<Model.TbBA_DistrictClassModel>(); //声明一个表实体集合 DAL.TbBA_DistrictClassDAL addr = new DAL.TbBA_DistrictClassDAL(); list = addr.GetAddress(); //取回表实体集合 TreeNode fad = new TreeNode(); //顶节点 fad.Tag = 0; fad.Text = "全国"; Stopwatch watch = new Stopwatch(); watch.Start(); //计时 // addChild(list, fad, null, 0); Load_tVAddress(list, fad); //开始调用方法 tvAddress.Nodes.Add(fad); watch.Stop(); //计时结束 Console.WriteLine(watch.ElapsedMilliseconds); } #region v1 加载子节点 addChild(List<Model.TbBA_DistrictClassModel> lis, TreeNode fader, string pid) 此方法递归重复循环了N多次集合,其中多是无用功。 /// <summary> /// 递归加载子节点 /// </summary> /// <param name="lis">地区集合</param> /// <param name="fader">父节点</param> /// <param name="pid">父节点号</param> void addChild(List<Model.TbBA_DistrictClassModel> lis, TreeNode fader, string pid, int j) { for (int i = j; i < lis.Count; i++) { Model.TbBA_DistrictClassModel ad = lis[i]; if (ad.Parent == pid) { TreeNode child = new TreeNode(); child.Tag = ad.Parent; child.Text = ad.iName; //加进父节点 fader.Nodes.Add(child); addChild(lis, child, ad.iCode, i); //调用本身 } } } #endregion #region v2 此方法只循环一次 list 集合比递归方法效率高出很多。 /// <summary> /// 非递归用 foreach 加载节点 /// </summary> private void Load_tVAddress(List<Model.TbBA_DistrictClassModel> list, TreeNode fad) { for (int i = 0; i < list.Count; i++) // foreach (Model.TbBA_DistrictClassModel ad in list) { TreeNode tn = new TreeNode(); Model.TbBA_DistrictClassModel ad = list[i]; //循环取集合中上一个对象 tn.Tag = ad.Parent; //记录父节点号 tn.Text = ad.iName; //记录自身节名 tn.Name = ad.iCode; //记录自身节点号 if (ad.Parent == null) //是否有父节点 { fad.Nodes.Add(tn); int j; j = tn.Index; } else //进入第二级 { foreach (TreeNode t2 in fad.Nodes) //取第二级节点 { if (t2.Name == ad.Parent) //寻找子节点 { t2.Nodes.Add(tn); //添加子节点 } else //进入第三级 { foreach (TreeNode t3 in t2.Nodes) //取第三级节点 { if (t3.Name == ad.Parent) { t3.Nodes.Add(tn); //添加子节点 } } } } } } } #endregion #region v3 /// <summary> /// 非递归用for + foreach 加载节点 /// </summary> private void Load_tVAddress2(List<Model.TbBA_DistrictClassModel> list, TreeNode fad) { for (int i = 0; i < list.Count; i++) { TreeNode tn = new TreeNode(); Model.TbBA_DistrictClassModel ad = list[i]; tn.Tag = ad.Parent; tn.Text = ad.iName; tn.Name = ad.iCode; if (ad.Parent == null) //是否有父节点 { fad.Nodes.Add(tn); int j; j = tn.Index; } else { int index = fad.Index; for (int i1 = 0; i1 < fad.Nodes.Count; i1++) { TreeNode t2 = fad.Nodes[index + i1]; if (t2.Name == ad.Parent) { t2.Nodes.Add(tn); } else { foreach (TreeNode t3 in t2.Nodes) // for (int i2 = 0; i2 < t2.Nodes.Count; i2++) { // TreeNode t3 = t2.Nodes[t2.Index + i2]; if (t3.Name == ad.Parent) { t3.Nodes.Add(tn); } } } } } } } #endregion }
数据表中的数据形式图: