通过hashtable,建立树形结构

     做项目过程中,经常会遇到树形结构的表,那怎么把这些entity建立树形结构呢?

 

本文讲述的是存在父子结构的entity建立树结构,最后在TreeView中呈现.

例如现在有一个地区表,

     Id      name     parentId

     1      福建       0

     2      福州       1

     3      厦门       1

     4      鼓楼       2

     5      湖南       0

     6      长沙       5

     7      上海       0

     8      北京       0

 

要呈现的结构为:

     福建

           --福州

               ----鼓楼

           --厦门

     湖南

           --长沙

     上海

     北京

 

像这种父子表的结构我们很多时候都要用了.

1. 抽象出一个ITreeNode接口,

 

ContractedBlock.gif ExpandedBlockStart.gif Code
     public  interface ITreeNode
    {
        
string Id{get;}

        
string ParentId { get;}

        ArrayList Children { 
get;}

    }

 

2.在ITreeNode接口的,实现树结构的生成.

 

 

ContractedBlock.gif ExpandedBlockStart.gif Code
public class Tree
ExpandedBlockStart.gifContractedBlock.gif    
{
        
private Hashtable _hs;
        
public Tree(Hashtable hs)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (hs == null)
                
throw new Exception("the hashtabe is null in Create tree");
            _hs 
= hs;
        }


        
public ArrayList CreateTree()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Hashtable parenths 
= new Hashtable();//保存顶级父亲节点
            Hashtable allNodes = new Hashtable();//保存已经添加到树结构的节点

            
foreach (DictionaryEntry entry in _hs)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (allNodes.Contains(entry.Key))
                    
continue;
                
if (entry.Value is ITreeNode)
                    InitTreeNode((ITreeNode)entry.Value, parenths, allNodes);
            }


            ArrayList roots 
= new ArrayList();
            
//将顶级节点添加到roots中
            foreach (DictionaryEntry entry in parenths)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                roots.Add(entry.Value);
            }

            
return roots;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 反向递归建立树结构
        
/// </summary>
        
/// <param name="treeNode">树节点</param>
        
/// <param name="parenths">保存顶级节点的hashtable</param>
        
/// <param name="allHs">已经建立节点的hashtable</param>

        private void InitTreeNode(ITreeNode treeNode, Hashtable parenths, Hashtable allHs)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            ITreeNode parentTreeNode;
            
//如果treenode已经添加,则返回不做任何操作
            if (allHs.Contains(treeNode.Id))
                
return;            
            
if (treeNode.ParentId == "0" || !_hs.Contains(treeNode.ParentId))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
//如果treenode不存在父节点,则被认为顶级节点
                if (!parenths.Contains(treeNode.Id))
                    parenths.Add(treeNode.Id, treeNode);
                
if (!allHs.Contains(treeNode.Id))
                    allHs.Add(treeNode.Id, treeNode);
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (parenths.Contains(treeNode.ParentId))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
//如果父亲节点在顶级节点中存在,则添加到顶级节点的孩子表中,并保存在已建树的hashtable中
                    parentTreeNode = (ITreeNode)parenths[treeNode.ParentId];
                    
if (!allHs.Contains(treeNode.Id))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        allHs.Add(treeNode.Id, treeNode);
                        parentTreeNode.Children.Add(treeNode);
                    }

                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
//如果父亲节点不在顶级节点了,则找到父亲节点,反向向上递归,直到找到顶级节点
                    parentTreeNode = (ITreeNode)_hs[treeNode.ParentId];
                    
if (!allHs.Contains(treeNode.Id))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        allHs.Add(treeNode.Id, treeNode);
                        parentTreeNode.Children.Add(treeNode);
                    }

                    InitTreeNode(parentTreeNode, parenths, allHs);
                }

            }

        }

    }

 

3 测试

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 private void btnTree_Click(object sender, EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
{
            Hashtable hs 
= new Hashtable();
            hs.Add(
"1"new Region("1""0""福建"));
            hs.Add(
"2"new Region("2""1""福州"));
            hs.Add(
"3"new Region("3""1""厦门"));
            hs.Add(
"4"new Region("4""2""鼓楼"));
            hs.Add(
"5"new Region("5""0""湖南"));
            hs.Add(
"6"new Region("6""5""长沙"));
            hs.Add(
"7"new Region("7""0""上海"));
            hs.Add(
"8"new Region("8""0""北京"));
            Tree tree 
= new Tree(hs);            
            
this.Controls.Add(InitTreeView(tree.CreateTree()));
        }

 

 

附上源码,大家可以调式看下

TreeTransform

 

     Happy Everyday

beldy

转载于:https://www.cnblogs.com/beldy/archive/2008/09/04/1284080.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值