㈠ 怎麼往資料庫里插入一個樹形結構的表,並且用一句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節點的子節點。