重慶分公司,新征程啟航
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊、服務(wù)器等服務(wù)
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊、服務(wù)器等服務(wù)
數(shù)據(jù)庫設(shè)計(jì)的時候,通常的做法是用父ID來解決樹狀結(jié)構(gòu),也有二叉樹等等
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊、虛擬主機(jī)、營銷軟件、網(wǎng)站建設(shè)、行唐網(wǎng)站維護(hù)、網(wǎng)站推廣。
id ?pid category_name
然后,用遞歸就能實(shí)現(xiàn),也有引用數(shù)組的方式
?php
/**
*?此方法由@Tonton?提供
*?
*?@date?2012-12-12?
*/
function?genTree5($items)?{?
foreach?($items?as?$item)?
$items[$item['pid']]['son'][$item['id']]?=?$items[$item['id']];?
return?isset($items[0]['son'])???$items[0]['son']?:?array();?
}?
/**
*?將數(shù)據(jù)格式化成樹形結(jié)構(gòu)
*?@author?Xuefen.Tong
*?@param?array?$items
*?@return?array?
*/
function?genTree9($items)?{
$tree?=?array();?//格式化好的樹
foreach?($items?as?$item)
if?(isset($items[$item['pid']]))
$items[$item['pid']]['son'][]?=?$items[$item['id']];
else
$tree[]?=?$items[$item['id']];
return?$tree;
}
$items?=?array(
1?=?array('id'?=?1,?'pid'?=?0,?'name'?=?'江西省'),
2?=?array('id'?=?2,?'pid'?=?0,?'name'?=?'黑龍江省'),
3?=?array('id'?=?3,?'pid'?=?1,?'name'?=?'南昌市'),
4?=?array('id'?=?4,?'pid'?=?2,?'name'?=?'哈爾濱市'),
5?=?array('id'?=?5,?'pid'?=?2,?'name'?=?'雞西市'),
6?=?array('id'?=?6,?'pid'?=?4,?'name'?=?'香坊區(qū)'),
7?=?array('id'?=?7,?'pid'?=?4,?'name'?=?'南崗區(qū)'),
8?=?array('id'?=?8,?'pid'?=?6,?'name'?=?'和興路'),
9?=?array('id'?=?9,?'pid'?=?7,?'name'?=?'西大直街'),
10?=?array('id'?=?10,?'pid'?=?8,?'name'?=?'東北林業(yè)大學(xué)'),
11?=?array('id'?=?11,?'pid'?=?9,?'name'?=?'哈爾濱工業(yè)大學(xué)'),
12?=?array('id'?=?12,?'pid'?=?8,?'name'?=?'哈爾濱師范大學(xué)'),
13?=?array('id'?=?13,?'pid'?=?1,?'name'?=?'贛州市'),
14?=?array('id'?=?14,?'pid'?=?13,?'name'?=?'贛縣'),
15?=?array('id'?=?15,?'pid'?=?13,?'name'?=?'于都縣'),
16?=?array('id'?=?16,?'pid'?=?14,?'name'?=?'茅店鎮(zhèn)'),
17?=?array('id'?=?17,?'pid'?=?14,?'name'?=?'大田鄉(xiāng)'),
18?=?array('id'?=?18,?'pid'?=?16,?'name'?=?'義源村'),
19?=?array('id'?=?19,?'pid'?=?16,?'name'?=?'上壩村'),
);
echo?"pre";
print_r(genTree5($items));
print_r(genTree9($items));
?
可以參考以下代碼,但需要把你自己的數(shù)據(jù)庫鏈接,表等改一下就可以了
html
head
link href='style.css' rel=stylesheet
meta http-equiv="Content-Type" content="text/html; charset=utf-8" /
script language="JavaScript" src="TreeMenu.js"/script
/head
body
?php
//基本變量設(shè)置
$GLOBALS["ID"] =1; //用來跟蹤下拉菜單的ID號
$layer=1; //用來跟蹤當(dāng)前菜單的級數(shù)
//連接數(shù)據(jù)庫
$Con=mysql_connect("localhost","root","1234");
mysql_select_db("wiki");
//提取一級菜單
$sql="SELECT * FROM wiki where pid=0";
$result=mysql_query($sql,$Con);
//如果一級菜單存在則開始菜單的顯示
if(mysql_num_rows($result)0) ShowTreeMenu($Con,$result,$layer,$ID);
//=============================================
//顯示樹型菜單函數(shù) ShowTreeMenu($con,$result,$layer)
//$con:數(shù)據(jù)庫連接
//$result:需要顯示的菜單記錄集
//layer:需要顯示的菜單的級數(shù)
//=============================================
function ShowTreeMenu($Con,$result,$layer)
{
//取得需要顯示的菜單的項(xiàng)目數(shù)
$numrows=mysql_num_rows($result);
//開始顯示菜單,每個子菜單都用一個表格來表示
echo "table cellpadding='0' cellspacing='0' border='0'";
for($rows=0;$rows$numrows;$rows++)
{
//將當(dāng)前菜單項(xiàng)目的內(nèi)容導(dǎo)入數(shù)組
$menu=mysql_fetch_array($result);
//提取菜單項(xiàng)目的子菜單記錄集
$sql="select * from wiki where pid=$menu[cid]";
$result_sub=mysql_query($sql,$Con);
echo "tr";
//如果該菜單項(xiàng)目有子菜單,則添加JavaScript onClick語句
if(mysql_num_rows($result_sub)0)
{
echo "td width='20'img src='folder.gif' border='0'/td";
echo "td class='Menu' onClick='javascript:ShowMenu(Menu".$GLOBALS["ID"].");'";
}
else
{
echo "td width='20'img src='file.gif' border='0'/td";
echo "td class='Menu'";
}
//如果該菜單項(xiàng)目沒有子菜單,并指定了超級連接地址,則指定為超級連接,
//否則只顯示菜單名稱
//if($menu[url]!="")
//echo "a href='$menu[cid]'$menu[name]/a";
//else
echo $menu['name'];
echo "
/td
/tr
";
//如果該菜單項(xiàng)目有子菜單,則顯示子菜單
if(mysql_num_rows($result_sub)0)
{
//指定該子菜單的ID和style,以便和onClick語句相對應(yīng)
echo "tr id=Menu".$GLOBALS["ID"]++." style='display:none'";
echo "td width='20' /td";
echo "td";
//將級數(shù)加1
$layer++;
//遞歸調(diào)用ShowTreeMenu()函數(shù),生成子菜單
ShowTreeMenu($Con,$result_sub,$layer);
//子菜單處理完成,返回到遞歸的上一層,將級數(shù)減1
$layer--;
echo "/td/tr";
}
//繼續(xù)顯示下一個菜單項(xiàng)目
}
echo "/table";
}
?
/body
/html
樹狀結(jié)構(gòu)的數(shù)據(jù)保存在數(shù)據(jù)庫中的常用方法有一下兩種:
1、鄰接表(adjacency list model)
2、預(yù)排序遍歷樹算法(modified preorder tree traversal algorithm)
用一下的例子討論這兩種方法的差異:
現(xiàn)有一棵樹如下:
鄰接表模式:
這種模式我們經(jīng)常用到,很多的教程和書中也介紹過。我們通過給每個節(jié)點(diǎn)增加一個屬性 parent 來表示這個節(jié)點(diǎn)的父節(jié)點(diǎn)從而將整個樹狀結(jié)構(gòu)通過平面的表描述出來。根據(jù)這個原則,例子中的數(shù)據(jù)可以轉(zhuǎn)化成如下的表:
我們看到 Pear 是Green的一個子節(jié)點(diǎn),Green是Fruit的一個子節(jié)點(diǎn)。而根節(jié)點(diǎn)'Food'沒有父節(jié)點(diǎn)。 為了簡單地描述這個問題, 這個例子中只用了name來表示一個記錄。 在實(shí)際的數(shù)據(jù)庫中,你需要用數(shù)字的id來標(biāo)示每個節(jié)點(diǎn),數(shù)據(jù)庫的表結(jié)構(gòu)大概應(yīng)該像這樣:id, parent_id, name, description。
以下是代碼:
?php
// $parent is the parent of the children we want to see
// $level is increased when we go deeper into the tree,
// used to display a nice indented tree
function display_children($parent, $level)
{
// 獲得一個 父節(jié)點(diǎn) $parent 的所有子節(jié)點(diǎn)
$result = mysql_query('SELECT name FROM tree '.
'WHERE parent="'.$parent.'";');
// 顯示每個子節(jié)點(diǎn)
while ($row = mysql_fetch_array($result))
{
// 縮進(jìn)顯示節(jié)點(diǎn)名稱
echo str_repeat(' ',$level).$row['name']."n";
//再次調(diào)用這個函數(shù)顯示子節(jié)點(diǎn)的子節(jié)點(diǎn)
display_children($row['name'], $level+1);
}
}
?
對整個結(jié)構(gòu)的根節(jié)點(diǎn)(Food)使用這個函數(shù)就可以打印出整個多級樹結(jié)構(gòu),由于Food是根節(jié)點(diǎn)它的父節(jié)點(diǎn)是空的,所以這樣調(diào)用: display_children('',0)。將顯示整個樹的內(nèi)容:
Food
Fruit
Red
Cherry
Yellow
Banana
Meat
Beef