多级树的遍历

  1. class MultilevelTree
  2. {
  3. private $depth;//深度
  4. private $i; //深度计数器
  5. private static $db ; //数据库对象
  6. public $arr; //节点数据数组
  7. public $deep; //最大深度
  8. function __construct($depth=0)
  9. {
  10. $this->depth = $depth;
  11. $this->i = 0;
  12. $this->arr = array();
  13. $this->deep = 0;
  14. }
  15. static function instanceDb(){
  16. if(!MultilevelTree::instanceDb()){
  17. return new DB();
  18. }else{
  19. return MultilevelTree::instanceDb();
  20. }
  21. }
  22. /**
  23. * 左序遍历
  24. * @param $uid 当前节点的id
  25. */
  26. function traversal_left($uid){
  27. $data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid);
  28. foreach ($data as $v){
  29. if($v['uid']){
  30. $this->arr[] = $v;
  31. $this->traversal_left($v['uid']);
  32. }
  33. }
  34. }
  35. /**
  36. * 根据层数遍历,并返回不包括本身的所有下层的数组
  37. * @param $uid 当前节点的id
  38. */
  39. function getChildren($uid){
  40. $this->i++;
  41. $data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid);
  42. $this->arr = array_merge($this->arr,$data);
  43. if($this->depth > 0){
  44. if($this->i == $this->depth){
  45. $this->i=1; //每当纵向一条树线等于深度时,将深度计数器重置为1
  46. return;
  47. }
  48. }
  49. foreach ($data as $v){
  50. if($v['uid']){
  51. $this->getChildren($v['uid']);
  52. }
  53. }
  54. }
  55. /**
  56. * 获取整棵树最大深度
  57. * @param $uid 当前节点的id
  58. */
  59. function getChildrenDepth($uid){
  60. $this->i++;
  61. $data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid);
  62. foreach ($data as $v){
  63. if($v['uid']){
  64. $data2 = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$v['uid']);
  65. if(!$data2){
  66. if($this->deep < $this->i) $this->deep = $this->i;
  67. $this->i=1; //每当没有子节点时,将计数器重置为初始值+1
  68. return;
  69. }
  70. $this->getChildrenDepth($v['uid']);
  71. }
  72. }
  73. }
  74. /**
  75. * 获取父级数据
  76. * @param $pid 当前节点的父级id
  77. */
  78. function getParent($pid){
  79. $parent = MultilevelTree::instanceDb()->row('select * from by_distribution where uid = '.$pid);
  80. if($this->i == $this->depth){
  81. return;
  82. }
  83. if($parent['pid'] == 0) array_push($this->arr,$parent);//根节点
  84. if($parent['pid']){
  85. array_push($this->arr,$parent);
  86. $this->i++;
  87. $this->getParent($parent['pid']);
  88. }
  89. }
  90. }

单元测试

  1. class TestMultilevelTree extends PHPUnit_Framework_TestCase
  2. {
  3. /**
  4. * 获取子节点数量
  5. */
  6. function testGetChildren(){
  7. $mlt = new MultilevelTree();
  8. $mlt->getChildren(1);
  9. $this->assertEquals(11,count($mlt->arr));
  10. }
  11. /**
  12. * 获取子节点最大深度
  13. */
  14. function testGetChildrenDepth(){
  15. $mlt = new MultilevelTree();
  16. $mlt->getChildrenDepth(1);
  17. $this->assertEquals(4,$mlt->deep);
  18. }
  19. /**
  20. * 获取获取父节点
  21. */
  22. function testGetParent(){
  23. $mlt = new MultilevelTree(10);
  24. $mlt->getParent(2);
  25. $this->assertEquals(2,count($mlt->arr));
  26. }
  27. }