JAVA组程序优化综合考试试题

题目原型:

有一张标准的树状结构表,里面有Structure_Id和 Parent_Id两个关键列,记录了结点的父子关系。现在要求添加一个字段为 Structure_Code ,标记为 三位一个节点关系,比如 第一级的为 001,002,第二级的为 001 001 , 001 002等,以此类推。

现在添加了这样一列:

想要的是这样的:

为什么要这样的东西呢?因为这列中可以描述:它的父亲是谁,爷爷是谁,太爷爷是谁,祖先是谁,当然也可以描述它的所有孩子有哪些,是居家必备,出门旅行的好东西啊!!!做树状设计时强烈推荐。

那么如何处理呢??这是个算法问题,请大家自行设计一下,我们对比一下执行效率。我的答案是5K条左右的数据,共需0.5秒。如果你的算法更优,请告诉我。

 我的思路,不要先看啊,请自行设计一下。

解决思路:

1、定义一个NodeBean,包括Structure_ID,Parent_ID,Structure_Code,Child_Count四个属性

2、创建一个数据结构var dict=new Dictionary<String, NodeBean>();

3、采用DataAdapter一次性将整表读入到内存,存放到dict中。

4、初始化根结点:查询所有根结点,然后按Stucture_ID做为Key,查询到dict中的此实例,然后把对应的NodeBean四个属性分别给定值,Parent_ID=11111-1111-1111-1111,Child_Count=0,Sturcture_Code分别为 001,002,003... 020等。

5、定义一个栈,FILO的东西,http://blog.csdn.net/aladdinty/article/details/3506285

Stack<string> stack = new Stack<string>(); 这个栈用来装需要马上找到父亲的节点。

6、遍历dict,找到第一条记录对应的Structure_Code,如果是空的,那么表示需要填充值,添加到上面定义好的栈里。

7、查找到对应的Parent_ID,然后拿此Parent_ID为KEY去dict中查找上一级节点对应的Structure_Code,

8、如果找到了,那么就可以更改父节点的,Child_Count++,表示又有一个孩子回家了。把父亲的Structure_Code放在前面,后面根据Child_Count记录001,002,003

9、如果还是没有找到,那么继续加入到定义好的栈里。

10、循环检查栈里面是不是有东西,有的话,遍历每一个,因为特殊的数据结构栈,所以是FILO的,就是先进后出,这样就把爷爷结点先和太爷爷结点建立起了关系,把它移除,然后处理父亲,最后处理孩子的。

 

OK,至此这个Dictionary整理完成,我们重新组装成SQL,一次性事务提交到数据库即可了。

 
View Code

附上代码实现:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.Diagnostics;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public class InsideBean
    {
        public String StructureId { get; set; }
        public String ParentId { get; set; }
    }
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //大字典
        readonly Dictionary<String, NodeBean> _dict = new Dictionary<String, NodeBean>();
        //定义一个堆
        readonly Stack<String> _stack = new Stack<String>();
        private String _sql = "";

        private void button1_Click(object sender, EventArgs e)
        {
            // 开始计时  
            var watch = new Stopwatch();
            watch.Start();  

            DbProviderFactory factory = SQLiteFactory.Instance;
            using (var conn = factory.CreateConnection())
            {
                // 连接数据库  
                if (conn != null)
                {
                    conn.ConnectionString = @"Data Source=c:
esource_db.db";
                    conn.Open();

                    //有哪些个学段科目
                    _sql = "select structure_id,parent_id,structure_node from t_resource_structure";
                    var adapter = new SQLiteDataAdapter(_sql, conn.ConnectionString);
                    var dataSet = new DataSet();
                    adapter.Fill(dataSet, "myTable");
                    var dt = dataSet.Tables[0];

                    for (var i = 0; i < dt.Rows.Count; i++)
                    {
                        var mybean=new NodeBean
                        {
                            Child_Count = 0,
                            Parent_ID = dt.Rows[i]["parent_id"].ToString(),
                            StructureId = dt.Rows[i]["structure_id"].ToString(),
                            Structure_Code = ""
                        };

                        _dict.Add(dt.Rows[i]["structure_id"].ToString(),mybean);
                    }
                    //给所有根结点初值
                    _sql = "select structure_id from t_resource_structure where structure_id=xdkm_id";
                    adapter = new SQLiteDataAdapter(_sql, conn.ConnectionString);
                    dataSet = new DataSet();
                    adapter.Fill(dataSet, "myTable");
                    dt = dataSet.Tables[0];

            
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        var code = 1000 + (i + 1);
                        var resultCode = code.ToString().Substring(1, 3);
                        _dict[dt.Rows[i][0].ToString()].Child_Count = 0;
                        _dict[dt.Rows[i][0].ToString()].Structure_Code = resultCode;
                    }
            
                    foreach (KeyValuePair<string, NodeBean> a in _dict)
                    {
                        if (a.Value.Structure_Code == "")
                        {
                            //入栈,表示这个家伙需要进行本轮处理
                            _stack.Push(a.Value.StructureId);

                            var currentBean = new InsideBean
                            {
                                ParentId = a.Value.Parent_ID,
                                StructureId = a.Value.StructureId
                            };

                            while (_stack.Count > 0)
                            {
                                if (_dict[currentBean.ParentId].Structure_Code == "")
                                {
                                    _stack.Push(currentBean.ParentId);
                                    //结构ID
                                    currentBean.StructureId = currentBean.ParentId;
                                    //结构的父ID
                                    currentBean.ParentId = _dict[currentBean.ParentId].Parent_ID;
                                }
                                else
                                {
                                    //找到了它父亲的东西
                                    _dict[currentBean.ParentId].Child_Count++;
                                    int code = 1000 + (_dict[currentBean.ParentId].Child_Count);
                                    String resultCode = code.ToString().Substring(1, 3);
                                    _dict[currentBean.StructureId].Structure_Code = _dict[currentBean.ParentId].Structure_Code + resultCode;
                                    //把父亲出栈
                                    _stack.Pop();
                                    //把这个父亲的儿子
                                    if (_stack.Count > 0)
                                    {
                                        //结构ID
                                        currentBean.StructureId = _stack.Peek();//取出顶层元素
                                        //结构的父ID
                                        currentBean.ParentId = _dict[_stack.Peek()].Parent_ID;
                                    }
                                }
                            }
                        }
                    }

                    //保存到数据库
                    _sql = "update t_resource_structure set structure_node=? where structure_id=?";
                    var cmd = conn.CreateCommand();  
                    var trans = conn.BeginTransaction();
                    cmd.Connection = conn;
                    cmd.CommandText = _sql;
                     // 添加参数  
                    cmd.Parameters.Add(cmd.CreateParameter());
                    cmd.Parameters.Add(cmd.CreateParameter());  
                    try
                    {
                        foreach (var a in _dict)
                        {
                            cmd.Parameters[0].Value = a.Value.Structure_Code;
                            cmd.Parameters[1].Value = a.Value.StructureId;
                            cmd.ExecuteNonQuery();
                        }
                        trans.Commit();
                    }
                    catch (Exception err)
                    {
                        trans.Rollback();
                        throw;
                    }
                }

                //更新一下资源与结构对应关系表
                 _sql =
                    "update t_resource_location set structure_node=(select t_resource_structure.structure_node from t_resource_structure where t_resource_structure.structure_id=t_resource_location.node_id)";
                using (var cmd2 = conn.CreateCommand())
                {
                    cmd2.Connection = conn;
                    cmd2.CommandText = _sql;
                    cmd2.ExecuteNonQuery();
                }
                conn.Close();
                // 停止计时  
                watch.Stop();
                MessageBox.Show("完成:耗时" + watch.Elapsed);
            }
        }
    }
}
View Code
原文地址:https://www.cnblogs.com/littlehb/p/3533261.html