【基础】一张表里的两个字段有父子关系,做成树。请教算法!
例如
表1
ID,name,fatherID
表2
ID,NAME,fatherID
表2 的fatherID与表1的ID关联
作成一张树,表2是叶子结点
尽可能少操作库
我用的递归,被老板骂得不行!!
可是我实在是没啥好办法?
问题点数:100、回复次数:13Top
1 楼wwfy(我舞飞扬)回复于 2006-08-03 15:14:20 得分 0
我用的递归,被老板骂得不行!!
为什么挨骂?你在递归里面频繁的操作数据库了?
树如果不大的话可以一次性的读取到DataTable里面,然后用DataTable.DefaultView.RowFilter设置条件筛选叶结点记录Top
2 楼Samen168(Code to coding)回复于 2006-08-03 15:25:50 得分 0
建树不用递归一条线往下不成,那可不叫树了,晕Top
3 楼Samen168(Code to coding)回复于 2006-08-03 15:26:11 得分 0
处理好数据读取提高下性能Top
4 楼Knight94(愚翁)回复于 2006-08-03 15:33:23 得分 0
ref:
http://blog.csdn.net/knight94/archive/2006/05/01/704281.aspxTop
5 楼lovebingye(降龙)回复于 2006-08-03 15:37:10 得分 0
可以简单说下你的树结构么,用数据举例!光是这样,不知道你的树的复杂程度。
正常设计树结构的时候都是用一个表实现的,比如
ID Index RootID
1 1 0
2 2 0
3 1 1
4 2 1
5 1 2
6 2 2
7 1 3
Top
6 楼sprc_lcl(cool一生)回复于 2006-08-03 15:41:46 得分 0
string sqlstr = "select id,name,0 as fatherid from tab1 union select 1000+id,name,fatherid from tab2";
执行付给一个dataset:ds
调用:buildtree(ds,0,"");
private void buildtree(DataSet ds,int firstfather,string firstnull)
{
System.Data.DataView dv=new System.Data.DataView();
dv.Table=ds.Tables[0];
dv.RowFilter = "fatherid=" + firstfather.ToString();
foreach(System.Data.DataRowView drv in dv)
{
Response.Write(firstnull+drv["name"].ToString());
string firstnull_1 = "|------";
BindDropDownList2(ds,drv["id"].ToString(),firstnull_1);
}
}
参考一下,依然是递归,只取一次数据库Top
7 楼loveme855(静静)回复于 2006-08-03 16:00:56 得分 0
我们用ADO
本来我想弄个数据结构,整个数组
老板说不要数据结构
我弄递归她说连库太频繁~~~~
我的叶子节点要存文件所以弄帐单独的表
大致意思
和lovebingye(降龙)的表一样
sprc_lcl(cool一生)
猛拥着中方法我们就不弄俩表了
不过谢谢~~~
还有是不是因为我是女生就可以无限制的要求啊~~~~
我现在准备用TABLE实现
Top
8 楼vigorlee371(一本正经)回复于 2006-08-03 16:24:10 得分 0
女程序员少见啊。我是菜鸟,我在程序里用的也是递归。关注中……Top
9 楼lzmtw(水如烟)回复于 2006-08-03 17:14:01 得分 0
刘胖子写了些数据库设计的文章,你可以参考:
http://blog.csdn.net/liu7537(他自己说是胖子刘)
他对树增加了一个层次字段,用来搜索
如
ID TypeName ParentID TypeLevel
1 根类别 0 000000
2 类别1 1 010000
3 类别1.1 2 010100
4 类别1.2 2 010200
5 类别2 1 020000
6 类别2.1 5 020100
7 类别3 1 030000
8 类别3.1 7 030100
9 类别3.2 7 030200
10 类别1.1.1 3 010101
Top
10 楼lzmtw(水如烟)回复于 2006-08-03 17:32:32 得分 0
引入层级字段后,我做了一个自联结表的通用类(原来叫树),象是如此:
Public MustInherit Class SinceLink(Of T As SinceLink.Item)
Private gCollection As SinceLink.Nodes(Of T)
Private gRoot As T
Private gCountOfLevel As Integer = 3 '层数。习惯称三层,再加上根,为四
Private gLengthEveryLevel() As Integer = {2, 2, 2} '每层位数。根为零
Private gTotalLength As Integer = 0 '总长度
Private gFirstIndexEveryLevel() As Integer = {0, 1, 3, 5} '每层的第一位位置
Private gCurrentIndexEveryLevel() As Integer = {0, 0, 0, 0} '每层的当前索引。根为零
Sub New(ByVal lengthEveryLevel As Integer())
gCountOfLevel = lengthEveryLevel.Length
gLengthEveryLevel = lengthEveryLevel
ReDim gFirstIndexEveryLevel(gCountOfLevel)
ReDim gCurrentIndexEveryLevel(gCountOfLevel)
gFirstIndexEveryLevel(0) = 0
gFirstIndexEveryLevel(1) = 0
Initialize()
End Sub
Item定义:
Partial Public Class SinceLink
<Serializable()> _
Public MustInherit Class Item
Private gID As Integer
Private gName As String
Private gDeclare As String
Private gParentID As Integer
Private gLevel As String
最后在三层四层之类的树稍为继承不用几行代码就OK了Top
11 楼lzmtw(水如烟)回复于 2006-08-03 17:38:05 得分 0
比如两层菜单的实现.如File->Exit.我在练习做一个插件类的主界面,只用两层。
定义非常简单,什么都不用加:
Namespace AddIns.Menu
<Serializable()> _
Public Class MenuItem
Inherits uCollection.SinceLink.Item
End Class
End Namespace
那个操作控制类仅只是将Item与相应菜单项关联起来,并做了初始化工作:
Imports System.Windows.Forms
Namespace AddIns.Menu
Public Class MenuManager
Inherits uCollection.SinceLink(Of MenuItem)
Private gMainForm As Windows.Forms.Form
Sub New(ByVal form As Form)
MyBase.New(New Integer() {2, 2, 2})
gMainForm = form
If Me.Collection.LastIndex = 1 Then Initialize()
End Sub
Private Sub Initialize()
AddMenu(Root, MenuEnum.File)
AddMenu(Root, MenuEnum.Edit)
AddMenu(Root, MenuEnum.View)
AddMenu(Root, MenuEnum.Format)
AddMenu(Root, MenuEnum.Tools)
AddMenu(Root, MenuEnum.Window)
AddMenu(Root, MenuEnum.Community)
AddMenu(Root, MenuEnum.Help)
AddMenu(Me.Collection.Items(MenuEnum.File.ToString, uCollection.SinceLink.Searchway.Name)(0), MenuEnum.Exit)
AddMenu(Me.Collection.Items(MenuEnum.File.ToString, uCollection.SinceLink.Searchway.Name)(0), MenuEnum.AddIns)
Me.Save()
End Sub
Private Sub AddMenu(ByVal parent As MenuItem, ByVal menu As MenuEnum)
Add(parent, menu.ToString).Declare = SR.GetString(String.Format("MenuItem_{0}", menu.ToString))
End Sub
Public Function AddMenuItem(ByVal item As MenuItem, ByVal action As EventHandler) As ToolStripMenuItem
Dim mToolStripMenuItem As ToolStripMenuItem = Nothing
If item.ParentID = Root.ID Then
mToolStripMenuItem = AddMenu(Nothing, item.Name, item.Declare, action)
Else
mToolStripMenuItem = AddMenu(GetMenuItem(Parent(item).Name), item.Name, item.Declare, action)
End If
Return mToolStripMenuItem
End Function
Public Function GetMenuItem(ByVal name As String) As ToolStripMenuItem
Dim mToolStripMenuItem As ToolStripMenuItem = Nothing
Dim mSearchResult As ToolStripItem()
Dim mKey As String = String.Format("{0}ToolStripMenuItem", name)
mSearchResult = gMainForm.MainMenuStrip.Items.Find(mKey, True)
If mSearchResult.Length = 1 Then
mToolStripMenuItem = CType(mSearchResult(0), ToolStripMenuItem)
End If
Return mToolStripMenuItem
End Function
Public Sub AddSeparatorItem(ByVal parent As ToolStripMenuItem)
parent.DropDownItems.Add(New ToolStripSeparator)
End Sub
Private Function AddMenu(ByVal parent As ToolStripMenuItem, ByVal name As String, ByVal text As String, ByVal action As EventHandler) As ToolStripMenuItem
Dim mMenuStrip As MenuStrip = gMainForm.MainMenuStrip
If mMenuStrip Is Nothing Then
mMenuStrip = New MenuStrip
gMainForm.Controls.Add(mMenuStrip)
gMainForm.MainMenuStrip = mMenuStrip
End If
Dim mToolStripMenuItem As ToolStripMenuItem = GetMenuItem(name)
If mToolStripMenuItem Is Nothing Then
mToolStripMenuItem = New ToolStripMenuItem(text)
Dim mKey As String = String.Format("{0}ToolStripMenuItem", name)
mToolStripMenuItem.Name = mKey
AddHandler mToolStripMenuItem.Click, action
If parent Is Nothing Then
mMenuStrip.Items.Add(mToolStripMenuItem)
Else
parent.DropDownItems.Add(mToolStripMenuItem)
End If
End If
Return mToolStripMenuItem
End Function
End Class
End Namespace
Top
12 楼lzmtw(水如烟)回复于 2006-08-03 17:41:01 得分 0
哦,那个可以实现三层菜单的,定义是如此
MyBase.New(New Integer() {2, 2, 2})Top
13 楼lzmtw(水如烟)回复于 2006-08-03 17:49:32 得分 0
这是一个插件。加载后主窗体加了一个菜单项 测试->Form
留意的是点击Form弹出一个窗体,这个窗体加上了基本的菜单项
并且File下头的Exit菜单与主窗体的某方法关联上了,换句话说,实现了插件与主窗体程序的交互,数据交流。
还是试试阶段,娱乐娱乐。
<Base.AddIns("TestForm", "AboutIns.TestForm", Author:="LzmTW", Description:="测试窗体", Version:="1.0.0.0", Lasttime:="2007年7月29日")> _
Public Class TestForm
Implements LzmTW.AddIns.Base.IPackage
Shared Sub Main()
End Sub
Dim f As Windows.Forms.Form
Private Test As Windows.Forms.ToolStripMenuItem
Private WithEvents TestForm As Windows.Forms.ToolStripMenuItem
Public Sub Load(ByVal appContext As Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase) Implements LzmTW.AddIns.Base.IPackage.Load
f = appContext.ApplicationContext.MainForm
Test = New Windows.Forms.ToolStripMenuItem("测试(&T)")
TestForm = New Windows.Forms.ToolStripMenuItem("Form(&F)")
Test.DropDownItems.Add(TestForm)
f.MainMenuStrip.Items.Add(Test)
Console.WriteLine(System.Reflection.Assembly.GetEntryAssembly.EntryPoint.DeclaringType.FullName)
End Sub
Public Sub Unload() Implements LzmTW.AddIns.Base.IPackage.Unload
f.MainMenuStrip.Items.Remove(Test)
End Sub
Private Sub TestForm_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TestForm.Click
Dim f1 As New Windows.Forms.Form
f1.Text = "this is a test from"
Dim t As New LzmTW.AddIns.Menu.MenuManager(f1)
For Each item As LzmTW.AddIns.Menu.MenuItem In t.Children(t.Root, False)
t.AddMenuItem(item, Nothing)
Next
Dim h As EventHandler = CType(eventhandler.CreateDelegate(GetType(EventHandler), f, "TestToolStripMenuItem_Click"), EventHandler)
For Each item As LzmTW.AddIns.Menu.MenuItem In t.Children(t.Collection.Items(Menu.MenuEnum.File.ToString, LzmTW.uCollection.SinceLink.Searchway.Name)(0), False)
t.AddMenuItem(item, h)
Next
f1.Show()
End Sub
Private Sub Hello(ByVal sender As Object, ByVal e As System.EventArgs)
MsgBox("Hello " & sender.ToString)
End Sub
End Class
Top




