Fork me on GitHub
听雨轩
生命易破碎,梦想只争朝夕!

    大四了,准备投简历找工作,今天刚好遇到一道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是我为了测试递归添加的四级节点,由此说明递归取得的结果是正确的。

 

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

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2010-10-21 21:54  流水殇  阅读(477)  评论(0编辑  收藏  举报