父子节点树形数据输出

    大四了,准备投简历找工作,今天刚好遇到一道c#面试题,我一般自我感觉良好,本想三下五除二解决掉的,没想到花了近一个小时的时间才解决掉 。

 

题目如上描述,从题目中我们可以得出以下几个要求:

1、ID是自增的,第一级节点的FID为0

2、SHOW为1的节点才显示,否则隐藏

3、同一个父节点下的子节点,如果SHOWDER相同,则ID大的不显示

4、题目好像只输出了三级节点,但是我想四级、五级甚至N级都应该可以输出,所以应该采用递归的方法实现

综合考虑上述题目要求,我的解决方案如下,一下代码是在Visual Studio 2008中实现的,其它版本的vs请参考,数据库创建过程略。

1、C#既然是面向对象的,我们就应该充分发挥它面向对象的优势,所以我创建了一个类Node用于表示一个数据节点

 

代码
 
   
using System.Collections.Generic;

namespace 面试OfferTest.Model
{
public class Node
{
public int ID { get ; set ; }
public int FID { get ; set ; }
public string nodeName { get ; set ; }
public int showder { get ; set ; }
public int show { get ; set ; }
public List < Node > childNodes { get ; set ; } // 这个Node下子节点列表
public bool flag { get ; set ; } // 指示该节点是否已经输出过
public Node()
{
childNodes
= new List < Node > (); // 为列表分配空间

}
}
}

2、读取数据初始化节点列表

 

代码
 
   
static void Main( string [] args)
{
var NodeList
= new List < Node > (); // 整个节点列表
var connstr = @" Data Source=.\SQLEXPRESS;AttachDbFilename=F:\C#\面试OfferTest\面试OfferTest\MyTest.mdf;Integrated Security=True;User Instance=True " ; // 这里为了方便就把连接字符串写死了,您最好放到配置文件中……
if (String.IsNullOrEmpty(connstr))
return ;

using (var conn = new SqlConnection(connstr))
{
if (conn.State == ConnectionState.Closed)
conn.Open();
var sqlstr
= " select * from TreeTest Order by ID " ;
var comm
= new SqlCommand(sqlstr, conn);
var reads
= comm.ExecuteReader();

while (reads.Read())
{
var node
= new Node
{
ID
= reads.GetInt32( 0 ),
FID
= reads.GetInt32( 1 ),
nodeName
= reads.GetString( 2 ),
showder
= reads.GetInt32( 3 ),
show
= reads.GetInt32( 4 ),
flag
= false

};


NodeList.Add(node);

if (node.FID != 0 ) // 如果不是一级节点就应该有父节点,把该节点添加到父节点的子节点列表
{
var parentnode
= NodeList.FirstOrDefault(p => p.ID == node.FID); // 查找父节点
if (parentnode == null ) return ;
if (parentnode.childNodes.FirstOrDefault(p => p.showder == node.showder) == null )
parentnode.childNodes.Add(node);
else
{
// 相同showder的设置为不显示
node.show = 0 ;
}
}


}

}

foreach (var row in NodeList.OrderBy(p => p.ID))
{
PrintTree(row,
0 ); // 递归输出节点信息

}
Console.Read();


}

 

 

 

3、递归函数的编写

 

代码
 
   

private static void PrintTree(Node node, int level)
{
// node表示待输出的节点,level表示它的深度,也就是它的级数-1
if (node == null ) return ;
if (node.show == 1 && node.flag == false )
{
var count
= level;
while (count > 0 )
{
Console.Write(
" | " );
count
-- ;


}
Console.WriteLine(
" |---- " + node.nodeName);
node.flag
= true ; // 设置该节点已经输出过了

}

if (node.childNodes != null )
{
foreach (var item in node.childNodes.OrderBy(p => p.showder))
{
PrintTree(item,level
+ 1 ); // 递归下一个节点
}

}

}

4、运行结果

1005-01-01-01是我为了测试递归添加的四级节点,由此说明递归取得的结果是正确的。

 

总结,由此看来面试题不容易,额,还需要狂补知识啊。呵呵,笑话,一笑而过……

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/yuananyun/archive/2010/10/21/1857834.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值