大四了,准备投简历找工作,今天刚好遇到一道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是我为了测试递归添加的四级节点,由此说明递归取得的结果是正确的。
总结,由此看来面试题不容易,额,还需要狂补知识啊。呵呵,笑话,一笑而过……