(無限級 非遞迴)樹形分類

2022-03-05 07:43:55 字數 4541 閱讀 7416

記得之前有一次去面試,被問了無限級怎麼做。我想很簡單,就說了最基本的結構:id、name、parentid。

又被問就這樣嗎?顯然不被滿意。後面自然就沒通過面試。

遇上技術型面試官,如果問的技術問題不被滿意,大抵就沒有下文了。遇上那些一副老子技術天下第一,狗眼看人低的面試官,那就自認倒霉吧。

遇上追問你如何規劃人生,比如五年規劃什麼的。筆者現在只堪堪在溫飽線上掙扎,只想提高點技術實力,多拿點工資。如果筆者有大能耐,就完全可以和面試官侃侃而談雄心壯志,也可以完全不甩面試官,甚至可以發出乙個鄙夷的眼光。奈何筆者沒什麼能耐,不得不認真回答面試官,卻又因為回答的空泛無力,還要被面試官指手畫腳一番。結果自然又是沒有下文。

畢竟樹形分類在**系統中,查詢是最頻繁的操作,反而在增刪改操作極少。所以在儲存到資料庫時,為了按樹形排序,增加了增刪改的複雜度,卻可以換來查詢上效能的提公升。

此方案的發明者無疑是充滿智慧型的。

不過我想,我只是剛好在實際工作中沒有用到它而已。

沒用過的技術或方案多了去。下次再遇上這種拿幾個技術問題唧唧歪歪的面試官,哥決定了不甩他。

本方案是在mysql+ci php mvc下設計的,所以命名習慣隨俗。

下面是表的設計結構

字段說明

id分類編號

parent_id

分類的父親節點

name

分類名稱

parent_path

父節點的路徑,用於找到乙個節點的子節點和子子節點或所有子節點。也可以找到乙個節點的所有父節點,比如在刪除節點時同時刪除其下所有子節點

order_path

所有節點按樹形排序,可以乙個sql語句提取樹形排序的分類,而不需要遞迴

level

第幾級節點,可以和css配合,美化和層次化顯示效果

order_id

輔助order_path完成同一級別下的排序

新增資料

有兩種情況:1.新增根結點 2.新增子節點

1.新增根結點

需要注意,parent_path=『0,』 ,

level=』0』  ,

order_id,'select max(order_id) as morder_id from info_class where parent_id=0』 ,morder_id存在,則order_id=morder_id+1,否則order_id=1  ,

order_path等於order_id前面補零,湊足四位。每乙個級別4位的編碼,可以存放0001~9999個分類,完全足夠使用。

2.新增子節點

需要注意,parent_path=父節點的parent_path+父節點的id+『,'   ,

level,通過把parent_path轉換為陣列,得到陣列長度來計算級別  ,

order_id,'select max(order_id) as morder_id from info_class where parent_id=父節點』 ,morder_id存在,則order_id=morder_id+1,否則order_id=1

order_path=父節點的order_path+order_id補零4位

**如下:

function insert()

else

$continue_add=$this->input->post('continue_add');

if($this->info_class_model->addclass($data))

redirect('index.php/submit_success','refresh');

}}

修改資料

有三種情況,1.根結點、或公升級為根結點 2.不更改父節點 3.更改父節點

1.根結點、或公升級為根結點

需要注意,parent_id=0  ,

parent_path=』0,』  ,

level=0  ,

如果是公升級為根節點:

order_id,'select max(order_id) as morder_id from info_class where parent_id=0』 ,morder_id存在,則order_id=morder_id+1,否則order_id=1  ,

order_path等於order_id前面補零,湊足四位。每乙個級別4位的編碼,可以存放0001~9999個分類,完全足夠使用。

2.不更改父節點

需要注意,parent_path=父節點的parent_path+父節點的id+『,'   ,

level,通過把parent_path轉換為陣列,得到陣列長度來計算級別  ,

3.更改父節點

需要注意,parent_path=父節點的parent_path+父節點的id+『,'   ,

level,通過把parent_path轉換為陣列,得到陣列長度來計算級別  ,

///old_order_path=該節點的原order_path,如果該節點有子節點,修改成功後,將子節點的order_path中old_order_path部分替換為新生成的order_path

order_id,'select max(order_id) as morder_id from info_class where parent_id=新父節點』 ,morder_id存在,則order_id=morder_id+1,否則order_id=1

temp_order_path等於order_id前面補零,湊足四位。

order_path=新父節點的order_path+temp_order_path

**如下:

function update($id)

}else

}if($this->info_class_model->updateclass($data))

redirect('index.php/submit_success','refresh');

}}

上移下移、或插入

只能在同一級別內,進行上移下移、或插入

1.上移

假設待上移節點為currentnode

根據currentnode獲取上乙個節點,再根據上乙個節點,獲取上上乙個節點就是待插入位置的節點,假設為brothernode,然後就可以把currentnode上移到brothernode之下了。

接下來,

獲取currentnode的父節點的order_path,假設為father_order_path

設定currentnode的order_id=brothernode的order_id+1

設定currentnode的order_path=father_order_path+currentnode的order_id補零四位

設定currentnode同一級別的其他節點,滿足order_id大於brothernode的order_id(不包括currentnode)條件的節點,order_id+1,order_path=father_order_path+order_id補零四位。

2.下移、插入

下移、插入都是在某乙個節點下插入,區別是下移是在下乙個節點下插入,而插入是選擇在某一節點下插入

獲取待下移節點為currentnode

獲取待插入位置的節點為brothernode

接下來,

獲取currentnode父節點的order_path,假設為father_order_path

設定currentnode的order_id=brothernode的order_id+1

設定currentnode的order_path=father_order_path+currentnode的order_id補零四位

設定currentnode同一級別的其他節點,滿足order_id大於brothernode的order_id(不包括currentnode)條件的節點,order_id+1,order_path=father_order_path+order_id補零四位。

上移和 下移、插入演算法基本一致,只有獲取待插入位置節點稍微有點不同。

查詢資料

select * from mini_info_class order by order_path

idparent_id

parent_path

name

order_path

order_id

level200

0,天庭

0022027

200,20,

日遊神00200111

600,冥府

0044026

60,6,

鬼差00400221

1100,妖域

005507

00,魔界00660

1200,人間道

0077029

00,修羅道00880

2829

0,29,

阿修羅00800111

PHP無限級分類實現(遞迴 非遞迴)

created by phpstorm.user qishou date 15 8 2 time 上午12 00 準備陣列,代替從資料庫中檢索出的資料 共有三個必須欄位id,name,pid header content type text html charset utf 8 categories...

PHP無限級分類實現(遞迴 非遞迴)

created by phpstorm.user qishou date 15 8 2 time 上午12 00 準備陣列,代替從資料庫中檢索出的資料 共有三個必須欄位id,name,pid header content type text html charset utf 8 categories...

PHP無限級分類實現(遞迴 非遞迴)

created by phpstorm.user qishou date 15 8 2 time 上午12 00 準備陣列,代替從資料庫中檢索出的資料 共有三個必須欄位id,name,pid header content type text html charset utf 8 categories...