㈠ 怎么往数据库里插入一个树形结构的表,并且用一句SQL语句将其遍历出来
树形结构统一使用下面的测试表与测试数据
CREATE TABLE test_tree (
test_id INT,
pid INT,
test_val VARCHAR(10),
PRIMARY KEY (test_id)
);
INSERT INTO test_tree VALUES(1, NULL, '.NET');
INSERT INTO test_tree VALUES(2, 1, 'C#');
INSERT INTO test_tree VALUES(3, 1, 'J#');
INSERT INTO test_tree VALUES(4, 1, 'ASP.NET');
INSERT INTO test_tree VALUES(5, 1, 'VB.NET');
INSERT INTO test_tree VALUES(6, NULL, 'J2EE');
INSERT INTO test_tree VALUES(7, 6, 'EJB');
INSERT INTO test_tree VALUES(8, 6, 'Servlet');
INSERT INTO test_tree VALUES(9, 6, 'JSP');
INSERT INTO test_tree VALUES(10, NULL, 'Database');
INSERT INTO test_tree VALUES(11, 10, 'DB2');
INSERT INTO test_tree VALUES(12, 10, 'MySQL');
INSERT INTO test_tree VALUES(13, 10, 'Oracle');
INSERT INTO test_tree VALUES(14, 10, 'SQL Server');
INSERT INTO test_tree VALUES(15, 13, 'PL/SQL');
INSERT INTO test_tree VALUES(16, 15, 'Function');
INSERT INTO test_tree VALUES(17, 15, 'Procere');
INSERT INTO test_tree VALUES(18, 15, 'Package');
INSERT INTO test_tree VALUES(19, 15, 'Cursor');
INSERT INTO test_tree VALUES(20, 14, 'T-SQL');
Oracle
使用 START WITH CONNECT BY
语句实现树状查询
SQL> ed
Wrote file afiedt.buf
1 SELECT
2 LPAD(' ', 2*(LEVEL-1)) || test_val AS test_val
3 FROM
4 test_tree
5 START WITH
6 test_id IN (1, 6, 10)
7* CONNECT BY PRIOR test_id = pid
SQL> /
TEST_VAL
-----------------------------------------------------------
.NET
C#
J#
ASP.NET
VB.NET
J2EE
EJB
Servlet
JSP
Database
DB2
TEST_VAL
-----------------------------------------------------------
MySQL
Oracle
PL/SQL
Function
Procere
Package
Cursor
SQL Server
T-SQL
20 rows selected.
SQL Server
使用 Common Table Expression (CTE) 来实现 递归调用。
1> WITH StepCTE
2> AS
3> (
4> SELECT
5> test_id,
6> pid,
7> test_val,
8> 1 as Lev
9> FROM
10> test_tree
11> WHERE
12> test_id IN (1,6,10)
13> UNION ALL
14> SELECT
15> T.test_id,
16> T.pid,
17> T.test_val,
18> CTE.Lev + 1
19> FROM
20> test_tree T INNER JOIN StepCTE CTE
21> ON T.pid = CTE.test_id
22> )
23> SELECT
24> test_id, pid, test_val, Lev
25> FROM StepCTE;
26> go
test_id pid test_val Lev
----------- ----------- ---------- -----------
1 NULL .NET 1
6 NULL J2EE 1
10 NULL Database 1
11 10 DB2 2
12 10 MySQL 2
13 10 Oracle 2
14 10 SQL Server 2
20 14 T-SQL 3
15 13 PL/SQL 3
16 15 Function 4
17 15 Procere 4
18 15 Package 4
19 15 Cursor 4
7 6 EJB 2
8 6 Servlet 2
9 6 JSP 2
2 1 C# 2
3 1 J# 2
4 1 ASP.NET 2
5 1 VB.NET 2
(20 行受影响)
㈡ foxtable怎么做树形数据
你想做的是目录树吧,在FoxTable中有两种方式可以实现。一是直接编辑目录树,二是用代码生成目录树。首先你要在窗体中插入一个目录树控件,在目录树控件的底部有一个小三角,点击就可以直接编辑。
㈢ 如何将数据库中的数据插入到树 Treeview 中拜托各位了 3Q
我的意思是如何将数据库中的数据显示到treeview1中的Treeview1.items.item 节点下面;表tbTree结构:tbTree( TreeId, (节点编号) TreeName, (节点名称) UpperTreeId (上级节点编号))UpperTreeId=NULL 表示根节点 查看原帖>>
㈣ EXCEL 怎么做目录树
1、在EXCEL 2010中,打开需要制做目录树的表格文档,选择数据区域内的任意单元格,点击“数据”,选择“排序”。
㈤ 数据结构-二叉查找树(查找,插入,删除,遍历)
二叉查找树是一颗空树,或者是具有一下性质的二叉树:
1.若根结点的左子树不为空,那么左子树上所有结点的值都小于根节点的值
2.若根结点的右子树不为空,那么右子树上所有结点的值都小于根节点的值
3.根节点的左子树和右子树也是二叉查找树
下图就是一颗二叉查找树,每个结点的值都大于他的左子树的所有结点的值,每个结点的值都小于他的右子树所有结点的值。
下图也是一个二叉查找树,虽然他是一个斜树,树的高度等于结点的数量,但是他也符合二叉查找树的定义(只是搜索的效率很低)。
从名字就可以看出,我们构造二叉查找树的作用是高效地查找、插入和删除。
比如,我们在图一所示的二叉查找树中查找数字5是否存在,查找的步骤如下:
1、5和结点④比较,5大于4,下一步我们要搜索结点④的右子树(根据二叉查找树的定义,一个结点值小于他的右子树上所有结点的值)
2、5和结点⑥比较,5小于6,下一步我们要搜索结点⑥的左子树
3、5等于结点5,查找成功
我们依然用图一作为例子,这次我们要在图一所示的二叉树中插入一个7,步骤如下:
1、7和根结点④比较,7大于4,下一步搜索右子树
2、7和结点⑥比较,7大于6,下一步搜索右子树
3、7和结点⑧比较,7小于8,下一步搜索左子树
4、8的左子树为空,那么这里就是7应该插入的位置,将7插入到8的左子树中。
如下如所示
删除结点比较复杂,我们需要分为四种情况。
我们以下图为例来分析这四种情况
用图四作为例子,我们需要删除结点9,步骤如下
1、我们首先要找到结点9的父节点8(如果要删除的结点没有父节点,也就是要删除的结点就是根结点,那么直接将树设置为空树即可)。
2、我们将结点9从其父节点8的右子树上删除。
用图四作为例子,我们要删除结点15,它只有左子树,删除的步骤如下
1、找到待删除的结点15
2、将结点15的左子结点的值12赋值给结点15
3、将结点结点12的左子树和右子树分别设置为待删除结点的左子树和右子树
如下图所示:
用图四作为例子,我们要删除结点5,和2.3.2类似,步骤如下
1、找到待删除的结点5
2、将结点5的右子结点的值8赋值给结点5
3、将结点结点8的左子树和右子树分别设置为待删除结点的左子树和右子树
首先我们应该知道,二叉查找树中序遍历时结点的值递增的(大家可以自己想一下为什么)。
用图四作为例子,我们要删除结点10,为了保持二叉查找树的性质,我们需要找到中序遍历中10的左边一个结点或者右边一个结点来替代10的位置,这里我们选择中序遍历中10的左边一个结点。删除的步骤如下
1、首先找到待删除的结点
2、找到中序遍历中10的左边的那个结点9和该节点的父节点8
3、删除结点9
4、将结点10的值替换为9
如下图所示
当二位查找树是一颗完全二叉树时,树的高度是log(n) + 1,那么查找,插入,删除的时间复杂度都是log(n)。
但是如果二叉查找树不平衡,更机端的情况下变为一个斜树,如图二所示,那么时间复杂度就会退化为O(n)。
这里我使用java来写二叉查找树的搜索,插入,删除。其他语言思路一样。
我创建了一个类BinarySearchTree,类中有一个静态内部类TreeNode用来表示二叉树的结点,类中有一个TreeNode类型成员变量head用来保存二叉查找树的根节点。
思路在第二章已经说明,这里就不多解释了。
大家多练练手,明白其中的原理即可。
㈥ AVL树的操作
旋转
AVL树的基本操作一般涉及运做同在不平衡的二叉查找树所运做的同样的算法。但是要进行预先或随后做一次或多次所谓的AVL 旋转。
假设由于在二叉排序树上插入结点而失去平衡的最小子树根结点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先结点),则失去平衡后进行进行的规律可归纳为下列四种情况:
单向右旋平衡处理LL:由于在*a的左子树根结点的左子树上插入结点,*a的平衡因子由1增至2,致使以*a为根的子树失去平衡,则需进行一次右旋转操作;
单向左旋平衡处理RR:由于在*a的右子树根结点的右子树上插入结点,*a的平衡因子由-1变为-2,致使以*a为根的子树失去平衡,则需进行一次左旋转操作;
双向旋转(先左后右)平衡处理LR:由于在*a的左子树根结点的右子树上插入结点,*a的平衡因子由1增至2,致使以*a为根的子树失去平衡,则需进行两次旋转(先左旋后右旋)操作。
双向旋转(先右后左)平衡处理RL:由于在*a的右子树根结点的左子树上插入结点,*a的平衡因子由-1变为-2,致使以*a为根的子树失去平衡,则需进行两次旋转(先右旋后左旋)操作。
插入
向AVL树插入可以通过如同它是未平衡的二叉查找树一样把给定的值插入树中,接着自底向上向根节点折回,于在插入期间成为不平衡的所有节点上进行旋转来完成。因为折回到根节点的路途上最多有 1.5 乘 log n 个节点,而每次 AVL 旋转都耗费恒定的时间,插入处理在整体上耗费 O(log n) 时间。在平衡的的二叉排序树Balanced BST上插入一个新的数据元素e的递归算法可描述如下:若BBST为空树,则插入一个数据元素为e的新结点作为BBST的根结点,树的深度增1; 若e的关键字和BBST的根结点的关键字相等,则不进行; 若e的关键字小于BBST的根结点的关键字,而且在BBST的左子树中不存在和e有相同关键字的结点,则将e插入在BBST的左子树上,并且当插入之后的左子树深度增加(+1)时,分别就下列不同情况处理之:BBST的根结点的平衡因子为-1(右子树的深度大于左子树的深度,则将根结点的平衡因子更改为0,BBST的深度不变; BBST的根结点的平衡因子为0(左、右子树的深度相等):则将根结点的平衡因子更改为1,BBST的深度增1; BBST的根结点的平衡因子为1(左子树的深度大于右子树的深度):则若BBST的左子树根结点的平衡因子为1:则需进行单向右旋平衡处理,并且在右旋处理之后,将根结点和其右子树根结点的平衡因子更改为0,树的深度不变; 若e的关键字大于BBST的根结点的关键字,而且在BBST的右子树中不存在和e有相同关键字的结点,则将e插入在BBST的右子树上,并且当插入之后的右子树深度增加(+1)时,分别就不同情况处理之。
删除
从AVL树中删除可以通过把要删除的节点向下旋转成一个叶子节点,接着直接剪除这个叶子节点来完成。因为在旋转成叶子节点期间最多有 log n个节点被旋转,而每次 AVL 旋转耗费恒定的时间,删除处理在整体上耗费 O(log n) 时间。
查找
在AVL树中查找同在一般BST完全一样的进行,所以耗费 O(log n) 时间,因为AVL树总是保持平衡的。不需要特殊的准备,树的结构不会由于查询而改变。(这是与伸展树查找相对立的,它会因为查找而变更树结构。)
㈦ 如何将这些数据,插入成树形框形式
.版本 2 .支持库 iext .支持库 HtmlView .子程序 _按钮1_被单击 .局部变量 插入位置, 整数型 插入位置 = 树型框1.加入项目 (-1, 编辑框1.内容, , , , , ) 超文本浏览框1.地址 = 树型框1.取项目文本 (插入位置) 用列表框多方便啊,为什么要用树...
㈧ 进化树中的数据是怎么添加上去的
进化树中的数据添加方式如下:
1.进入页面,打开一个进化树。
2.点击右边控制面板上的第二项,高级选项。
3.在Branch lengths上点击选择Display显示的选项。
4.设置后在进化树上就可以添加数据了。
㈨ 怎样从数据库中读取数据生成树
private DataSet ds;
private SqlDataAdapter sqlDataAdapter1;
private int maxnodeid;
private void Form1_Load(object sender, System.EventArgs e)
{
string strconn=ConfigurationSettings.AppSettings["ConnStr"];
sqlConnection1 = new SqlConnection(strconn);
this.sqlConnection1.Open();
//填充DataSet
this.CreateDataSet();
//从数据库中读取数据,通过递归生成树。
InitTree(this.treeView1.Nodes,"0");
}
private void CreateDataSet()
{
this.sqlDataAdapter1=new SqlDataAdapter("select * from s_menu ",this.sqlConnection1);
this.ds=new DataSet();
this.sqlDataAdapter1.Fill(ds,"tree");
}
private void InitTree(TreeNodeCollection Nds,string parentId)
{
DataView dv=new DataView();
TreeNode tmpNd;
string intId;
dv.Table=ds.Tables["tree"];
dv.RowFilter="ParentId='" + parentId + "'" ;
foreach(DataRowView drv in dv)
{
tmpNd=new TreeNode();
tmpNd.Tag=drv["NodeId"].ToString();
tmpNd.Text=drv["NodeName"].ToString();
Nds.Add(tmpNd);
intId=drv["ParentId"].ToString();
InitTree(tmpNd.Nodes,tmpNd.Tag.ToString());
}
}
//新增节点操作
private void insert(string type)
{//判断是新增树节点,还是子节点.
string strinsert="insert into s_menu values('{0}','{1}','{2}')";
string strformat="";
if(type=="sub")
strformat=string.Format(strinsert,maxnodeid.ToString(),this.selectnode.Tag.ToString(),this.strcomm);
else
strformat=string.Format(strinsert,maxnodeid.ToString(),"0",this.strcomm);
SqlCommand cmd=new SqlCommand(strformat,this.sqlConnection1);
cmd.ExecuteNonQuery();
}
//为新增节点算出最大的节点值,并以此值作为新增的节点ID值
private int GetMaxNodeid()
{
int pre=0,last=0;
DataSet maxds=new DataSet();
this.sqlDataAdapter1=new SqlDataAdapter("select nodeid from s_menu order by nodeid",this.sqlConnection1);
this.sqlDataAdapter1.Fill(maxds);
for(int i=0;i{
if(i+1{
pre=int.Parse(maxds.Tables[0].Rows[i][0].ToString());
last=int.Parse(maxds.Tables[0].Rows[i+1][0].ToString());
if(last-pre!=1)
return pre+1;
}
}
return last+1;
}
private void getallnode(TreeNode tn)
{
foreach(TreeNode node in tn.Nodes)
{
list.Add(node.Tag.ToString());
if(node.Nodes.Count>0)
{
getallnode(node);
}
}
}
private void treeView1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
//判断是否点击了某个节点
this.selectnode= this.treeView1.GetNodeAt (e.X ,e.Y );
if(selectnode==null)
this.isselected=false;
else
this.isselected=true;
}
private void menuAdd_Click(object sender, System.EventArgs e)
{//判断是否点击了某个节点,若没有点击了,则是新增一个树节点
if(isselected==false)
{//算出新增树节点的ID值
maxnodeid=GetMaxNodeid();
TreeNode tmpNd=new TreeNode();
//赋值
tmpNd.Tag=this.maxnodeid.ToString();
FormCommon frmCommon=new FormCommon();
DialogResult result= frmCommon.ShowDialog();
if(result==DialogResult.OK)
{//取到新增树节点的文本值
tmpNd.Text=frmCommon.strcomm;
this.strcomm=frmCommon.strcomm;
//新增树节点
this.treeView1.Nodes.Add(tmpNd);
//插入数据库(说明插入的是树节点)
this.insert("root");
//展开
this.selectnode.Expand();
}
}
else
{//判断是否点击了某个节点,若点击了,则是新增一个子节点
this.contextAddSub();
}
}
private void contextAddSub()
{//得到新增子节点的ID值
maxnodeid=GetMaxNodeid();
TreeNode tmpNd=new TreeNode();
//赋值
tmpNd.Tag=this.maxnodeid.ToString();
FormCommon frmCommon=new FormCommon();
DialogResult result= frmCommon.ShowDialog();
if(result==DialogResult.OK)
{//取到新增树节点的文本值
tmpNd.Text=frmCommon.strcomm;
this.strcomm=frmCommon.strcomm;
//新增子节点
this.selectnode.Nodes.Add(tmpNd);
//插入数据库(说明插入的是子节点)
this.insert("sub");
//展开
this.treeView1.SelectedNode.Expand();
}
}
//删除节点操作
private void menuDel_Click(object sender, System.EventArgs e)
{//新建一个ArrayList,用于保存要删除的节点下边的所有子节点
list=new ArrayList();
if(this.isselected==true)
{//得到删除的节点下边的所有子节点
getallnode(this.selectnode);
//把要删除的节点也加进去
list.Add(this.selectnode.Tag.ToString());
//循环从数据库中删除
for(int i=0;i{
string strdel="delete s_menu where nodeid='{0}'";
string strformat="";
strformat=string.Format(strdel,list[i]);
SqlCommand cmd=new SqlCommand(strformat,this.sqlConnection1);
cmd.ExecuteNonQuery();
}
//从树中删除
this.selectnode.Remove();
}
}
//修改节点的值
private void menuEdit_Click(object sender, System.EventArgs e)
{
if(this.isselected==true)
{
FormCommon frmCommon=new FormCommon();
DialogResult result= frmCommon.ShowDialog();
if(result==DialogResult.OK)
{
string strdel="update s_menu set nodename= '{1}' where nodeid='{0}'";
string strformat="";
strformat=string.Format(strdel,this.selectnode.Tag.ToString(),frmCommon.strcomm);
SqlCommand cmd=new SqlCommand(strformat,this.sqlConnection1);
cmd.ExecuteNonQuery();
this.selectnode.Text=frmCommon.strcomm;
}
}
}
//遍历所有节点.查找值
private void getvaluenode(TreeNodeCollection tn,string value)
{
foreach(TreeNode node in tn)
{
if(node.Nodes.Count>0)
{
getvaluenode(node.Nodes,value);
}
if(node.Text==value)
listnode.Add(node);
}
}
private void menuSearch_Click(object sender, System.EventArgs e)
{
int j,k;
this.listnode=new ArrayList();
FormCommon frmCommon=new FormCommon();
DialogResult result= frmCommon.ShowDialog();
if(result==DialogResult.OK)
{
TreeNode n =new TreeNode();
TreeNode temp=new TreeNode();
//下面的函数是填充listnode;
getvaluenode(this.treeView1.Nodes,frmCommon.strcomm);
for(int i=0;i{
j=0;k=0;
n=(TreeNode)listnode[i];
if (n != null)
{
temp=n;
//得到上面结点的数量,并将数量保存到变量j;
for(;n.Parent!=null;)
{
n=n.Parent;
j++;
}
//恢复原值
n=temp;
//新建一个树结点数组做保存得到查询到的所有节点.
TreeNode[] m=new TreeNode[j];
for(;n.Parent!=null;)
{
n=n.Parent;
m[k]=n;
k++;
}
for(int p=0;pm[p].Expand();
n=temp;
n.ForeColor=Color.Red;
}
}
}
}
private void treeView1_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e)
{
if(this.treeView1.SelectedNode.Text!=null)
{
string strdel="update s_menu set nodename= '{1}' where nodeid='{0}'";
string strformat="";strformat=string.Format(strdel,this.treeView1.SelectedNode.Tag.ToString(),e.Label.ToString());SqlCommand cmd=new SqlCommand(strformat,this.sqlConnection1);
cmd.ExecuteNonQuery();
}
}
private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
this.listBox1.Items.Clear();
this.listBox1.Items.Add(this.treeView1.SelectedNode.FullPath.ToString());
}
}
}
㈩ 如何在数据库中存储一棵树
假设有如下一棵树:
这种结构下,如果查询某一个节点的直接子节点,十分容易,比如要查询D节点的子节点。