文档章节

基于左右值的无限分类算法

bengozhong
 bengozhong
发布于 2016/09/09 11:38
字数 1273
阅读 32
收藏 1

基于左右值的无限分类算法,php,由于之前采用的递归排序无限分类方法感觉不是很理想,于是参考了国外同国内的左右值排序相关方法,自己写了一个基于左右值的无限分类类,欢迎大家测试,另外还有用到一个MySQL操作类,由于不是原创就不提供了,如果需要的可以PM我

 

[php] view plain copy

 

  1. <?php  
  2. /** 
  3.  * 基于左右值排序的无限分类算法 
  4.  * 数据库结果为 
  5. CREATE TABLE om_catagory ( 
  6.     CatagoryID int(10) unsigned NOT NULL auto_increment, 
  7.  Name varchar(50) default '', 
  8.     Lft int(10) unsigned NOT NULL default '0', 
  9.     Rgt int(10) unsigned NOT NULL default '0', 
  10.     PRIMARY KEY (id), 
  11.     KEY lft (lft), 
  12.     KEY rgt (rgt)  
  13.  * 更多的关于左右值排序的例子 
  14.  * http://www.chinaunix.net/jh/27/239532.html(http://dev.mysql.com/tech-resources/articles/hierarchical-data.html) 
  15.  * @author [email]psdshow@yahoo.com.cn[/email]  
  16.  * @version      1.0 
  17.  * @copyright psdshow 
  18.  * 欢迎光临我的个人日志 http://www.dayanmei.com 
  19.  */  
  20. class sortclass  
  21. {  
  22.   
  23. /** 
  24.  * Description 
  25.  * @var        
  26.  * @since     1.0 
  27.  * @access    private 
  28.  */  
  29. var $db;  
  30.   
  31. /** 
  32.  * Description 
  33.  * @var        
  34.  * @since     1.0 
  35.  * @access    private 
  36.  */  
  37. var $tablefix;  
  38.   
  39. /** 
  40.  * Short description.  
  41.  * 构造函数,引入数据库操作类函数 
  42.  * Detail description 
  43.  * @param      none 
  44.  * @global     none 
  45.  * @since      1.0 
  46.  * @access     private 
  47.  * @return     void 
  48.  * @update     date time 
  49. */  
  50. function sortclass()  
  51. {  
  52. global $db;  
  53. $this->db=$db;  
  54. $this->tablefix="om_";  
  55. } // end func  
  56.   
  57. /** 
  58.  * Short description.  
  59.  * 增加新的分类 
  60.  * Detail description 
  61.  * @param      none 
  62.  * @global     none 
  63.  * @since      1.0 
  64.  * @access     private 
  65.  * @return     void 
  66.  * @update     date time 
  67. */  
  68. function addsort($CatagoryID,$SortName)  
  69. {  
  70. if($CatagoryID==0){  
  71.  $Lft=0;  
  72.  $Rgt=1;  
  73.  }else{  
  74.  $Result=$this->checkcatagory($CatagoryID);  
  75.  //取得父类的左值,右值  
  76.  $Lft=$Result['Lft'];  
  77.  $Rgt=$Result['Rgt'];  
  78.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+2 WHERE `Lft`>$Rgt");  
  79.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+2 WHERE `Rgt`>=$Rgt");  
  80.  }  
  81.   
  82. //插入  
  83. if($this->db->query("INSERT INTO `".$this->tablefix."catagory` SET `Lft`='$Rgt',`Rgt`='$Rgt'+1,`Name`='$SortName'")){  
  84.  //$this->referto("成功增加新的类别","JAVASCRIPT:HISTORY.BACK(1)",3);  
  85.  return 1;  
  86.  }else{  
  87.  //$this->referto("增加新的类别失败了","JAVASCRIPT:HISTORY.BACK(1)",3);  
  88.  return -1;  
  89.  }  
  90. } // end func  
  91.   
  92.   
  93. /** 
  94.  * Short description.  
  95.  * 删除类别 
  96.  * Detail description 
  97.  * @param      none 
  98.  * @global     none 
  99.  * @since      1.0 
  100.  * @access     private 
  101.  * @return     void 
  102.  * @update     date time 
  103. */  
  104. function deletesort($CatagoryID)  
  105. {  
  106. //取得被删除类别的左右值,检测是否有子类,如果有就一起删除  
  107. $Result=$this->checkcatagory($CatagoryID);  
  108. $Lft=$Result['Lft'];  
  109. $Rgt=$Result['Rgt'];  
  110. //执行删除  
  111. if($this->db->query("DELETE FROM `".$this->tablefix."catagory` WHERE `Lft`>=$Lft AND `Rgt`<=$Rgt")){  
  112.  $Value=$Rgt-$Lft+1;  
  113.  //更新左右值  
  114.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value WHERE `Lft`>$Lft");  
  115.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value WHERE `Rgt`>$Rgt");  
  116.  //$this->referto("成功删除类别","javascript:history.back(1)",3);  
  117.  return 1;  
  118.  }else{  
  119.  //$this->referto("删除类别失败了","javascript:history.back(1)",3);  
  120.  return -1;  
  121.  }  
  122. } // end func  
  123.   
  124.    
  125.   
  126. /** 
  127.  * Short description.  
  128.  * 1,所有子类,不包含自己;2包含自己的所有子类;3不包含自己所有父类4;包含自己所有父类 
  129.  * Detail description 
  130.  * @param      none 
  131.  * @global     none 
  132.  * @since      1.0 
  133.  * @access     private 
  134.  * @return     void 
  135.  * @update     date time 
  136. */  
  137. function getcatagory($CatagoryID,$type=1)  
  138. {  
  139. $Result=$this->checkcatagory($CatagoryID);  
  140. $Lft=$Result['Lft'];  
  141. $Rgt=$Result['Rgt'];  
  142. $SeekSQL="SELECT * FROM `".$this->tablefix."catagory` WHERE ";  
  143. switch ($type) {  
  144.     case "1":  
  145.   $condition="`Lft`>$Lft AND `Rgt`<$Rgt";  
  146.   break;  
  147.  case "2":  
  148.   $condition="`Lft`>=$Lft AND `Rgt`<=$Rgt";  
  149.   break;  
  150.     case "3":  
  151.      $condition="`Lft`<$Lft AND `Rgt`>$Rgt";  
  152.      break;   
  153.  case "4":  
  154.   $condition="`Lft`<=$Lft AND `Rgt`>=$Rgt";  
  155.   break;  
  156.  default :  
  157.   $condition="`Lft`>$Lft AND `Rgt`<$Rgt";  
  158.   ;  
  159.  }   
  160. $SeekSQL.=$condition." ORDER BY `Lft` ASC";  
  161. $Sorts=$this->db->getrows($SeekSQL);  
  162. return $Sorts;  
  163. } // end func  
  164.   
  165.   
  166. /** 
  167.  * Short description.  
  168.  * 取得直属父类 
  169.  * Detail description 
  170.  * @param      none 
  171.  * @global     none 
  172.  * @since      1.0 
  173.  * @access     private 
  174.  * @return     void 
  175.  * @update     date time 
  176. */  
  177. function getparent($CatagoryID)  
  178. {  
  179. $Parent=$this->getcatagory($CatagoryID,3);  
  180. return $Parent;  
  181. } // end func  
  182. /** 
  183.  * Short description.  
  184.  * 移动类,如果类有子类也一并移动 
  185.  * Detail description 
  186.  * @param      none 
  187.  * @global     none 
  188.  * @since      1.0 
  189.  * @access     private 
  190.  * @return     void 
  191.  * @update     date time 
  192. */  
  193. function movecatagory($SelfCatagoryID,$ParentCatagoryID)  
  194. {  
  195. $SelfCatagory=$this->checkcatagory($SelfCatagoryID);  
  196. $NewCatagory=$this->checkcatagory($ParentCatagoryID);  
  197.   
  198. $SelfLft=$SelfCatagory['Lft'];  
  199. $SelfRgt=$SelfCatagory['Rgt'];  
  200. $Value=$SelfRgt-$SelfLft;  
  201. //取得所有分类的ID方便更新左右值  
  202. $CatagoryIDS=$this->getcatagory($SelfCatagoryID,2);  
  203. foreach($CatagoryIDS as $v){  
  204.  $IDS[]=$v['CatagoryID'];  
  205.  }  
  206. $InIDS=implode(",",$IDS);  
  207.   
  208. $ParentLft=$NewCatagory['Lft'];  
  209. $ParentRgt=$NewCatagory['Rgt'];  
  210. //print_r($InIDS);  
  211. //print_r($NewCatagory);  
  212. //print_r($SelfCatagory);  
  213. //exit;  
  214. if($ParentRgt>$SelfRgt){  
  215.  $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value-1 WHERE `Lft`>$SelfRgt AND `Rgt`<=$ParentRgt";  
  216.  $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value-1 WHERE `Rgt`>$SelfRgt AND `Rgt`<$ParentRgt";  
  217.  $TmpValue=$ParentRgt-$SelfRgt-1;  
  218.  $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$TmpValue,`Rgt`=`Rgt`+$TmpValue WHERE `CatagoryID` IN($InIDS)";  
  219.  }else{  
  220.  $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$Value+1 WHERE `Lft`>$ParentRgt AND `Lft`<$SelfLft";  
  221.  $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+$Value+1 WHERE `Rgt`>=$ParentRgt AND `Rgt`<$SelfLft";  
  222.  $TmpValue=$SelfLft-$ParentRgt;  
  223.  $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$TmpValue,`Rgt`=`Rgt`-$TmpValue WHERE `CatagoryID` IN($InIDS)";  
  224.  }  
  225. $this->db->query($UpdateLeftSQL);  
  226. $this->db->query($UpdateRightSQL);  
  227. $this->db->query($UpdateSelfSQL);  
  228. //$this->referto("成功移动类别","javascript:history.back(1)",3);  
  229. return 1;  
  230. } // end func  
  231.   
  232. /** 
  233.  * Short description.  
  234.  * 
  235.  * Detail description 
  236.  * @param      none 
  237.  * @global     none 
  238.  * @since      1.0 
  239.  * @access     private 
  240.  * @return     void 
  241.  * @update     date time 
  242. */  
  243. function checkcatagory($CatagoryID)  
  244. {  
  245. //检测父类ID是否存在  
  246. $SQL="SELECT * FROM `".$this->tablefix."catagory` WHERE `CatagoryID`='$CatagoryID' LIMIT 1";  
  247. $Result=$this->db->getrow($SQL);  
  248. if(count($Result)<1){  
  249.  $this->referto("父类ID不存在,请检查","javascript:history.back(1)",3);  
  250.  }  
  251. return $Result;    
  252. } // end func  
  253.   
  254. /** 
  255.  * Short description.  
  256.  * 
  257.  * Detail description 
  258.  * @param      none 
  259.  * @global     none 
  260.  * @since      1.0 
  261.  * @access     private 
  262.  * @return     array($Catagoryarray,$Deep) 
  263.  * @update     date time 
  264. */  
  265. function sort2array($CatagoryID=0)  
  266. {  
  267.   $Output = array();  
  268.   if($CatagoryID==0){  
  269.  $CatagoryID=$this->getrootid();  
  270.  }  
  271.   if(empty($CatagoryID)){  
  272.  return array();  
  273.  exit;  
  274.  }  
  275.   $Result = $this->db->query('SELECT Lft, Rgt FROM `'.$this->tablefix.  
  276.                         'catagory` WHERE `CatagoryID`='.$CatagoryID);   
  277.   if($Row = $this->db->fetch_array($Result)) {  
  278.   $Right = array();   
  279.   $Query = 'SELECT * FROM `'.$this->tablefix.  
  280.              'catagory` WHERE Lft BETWEEN '.$Row['Lft'].' AND '.   
  281.              $Row['Rgt'].' ORDER BY Lft ASC';  
  282.     
  283.   $Result = $this->db->query($Query);   
  284.     while ($Row = $this->db->fetch_array($Result)) {   
  285.       if (count($Right)>0) {   
  286.   while ($Right[count($Right)-1]<$Row['Rgt']) {   
  287.   array_pop($Right);  
  288.   }   
  289.      }  
  290.  $Output[]=array('Sort'=>$Row,'Deep'=>count($Right));  
  291.     $Right[] = $Row['Rgt'];  
  292.     }  
  293.   }  
  294.   return $Output;     
  295. } // end func  
  296.   
  297.   
  298. /** 
  299.  * Short description.  
  300.  * 
  301.  * Detail description 
  302.  * @param      none 
  303.  * @global     none 
  304.  * @since      1.0 
  305.  * @access     private 
  306.  * @return     void 
  307.  * @update     date time 
  308. */  
  309. function getrootid()  
  310. {  
  311. $Query="SELECT * FROM`".$this->tablefix."catagory` ORDER BY `Lft` ASC LIMIT 1";  
  312. $RootID=$this->db->getrow($Query);  
  313. if(count($RootID)>0){  
  314.  return $RootID['CatagoryID'];  
  315.  }else{  
  316.  return 0;  
  317.  }  
  318. } // end func  
  319.   
  320. /** 
  321.  * Short description.  
  322.  * 
  323.  * Detail description 
  324.  * @param      none 
  325.  * @global     none 
  326.  * @since      1.0 
  327.  * @access     private 
  328.  * @return     void 
  329.  * @update     date time 
  330. */  
  331. function referto($msg,$url,$sec)  
  332. {  
  333.  echo "<meta http-equiv="Content-Type" content="text/html; charset=utf-8">";  
  334.  echo "<meta http-equiv=refresh content=$sec;URL=$url>";  
  335.    if(is_array($msg)){  
  336.  foreach($msg as $key=>$value){  
  337.   echo $key."=>".$value."<br>";  
  338.         }  
  339.         }else{  
  340.         echo $msg;  
  341.         }  
  342.    exit;  
  343. } // end func  
  344. } // end class  
  345.   
  346. ?>  

© 著作权归作者所有

bengozhong
粉丝 19
博文 476
码字总数 485469
作品 0
深圳
程序员
私信 提问
开源 .NET CMS 系统--AtNet.CMS

Ops.cms 是基于 asp.net mvc + DDD 构架的开源 .NET CMS 系统。 可配置+易扩展+轻量级+跨平台 特性: 跨平台 支持Windows、Linux、MacOX运行。linux运行案例:http://blog.ops.cc DDD领域驱动...

刘铭88
2014/12/26
13.5K
1
树形结构的数据库表Schema设计

程序设计过程中,我们常常用树形结构来表征某些数据的关联关系,如企业上下级部门、栏目结构、商品分类等等,通常而言,这些树状结构需要借助于数据库完成持久化。然而目前的各种基于关系的数...

Sub
2013/03/25
0
2
前序遍历二叉树算法在无限极分类中的使用

大家通常都是使用递归实现无限极分类,都知道递归效率很低,下面介绍一种改进的前序遍历树算法,不适用递归实现无限极分类,在大数据量实现树状层级结构的时候效率更高。 原理实现: 按树状显...

Corwien
2016/06/06
59
0
树形结构的数据库表Schema设计

程序设计过程中,我们常常用树形结构来表征某些数据的关联关系,如企业上下级部门、栏目结构、商品分类等等,通常而言,这些树状结构需要借助于数据库完成持久化。然而目前的各种基于关系的数...

jiyayun
2013/10/22
0
1
无限级分类实现思路 (组织树的分级管理)

关于该问题,暂时自己还没有深入研究,在网上找到几种解决方案,各有优缺点。 第一种方案: 使用递归算法,也是使用频率最多的,大部分开源程序也是这么处理,不过一般都只用到四级分类。这种...

bengozhong
2016/09/09
43
0

没有更多内容

加载失败,请刷新页面

加载更多

在阿里云ecs服务器(linux之centos系统)安装调试nginx

购买阿里云ecs服务器实例 由于这里只是测试,我们就随便买一个(当然我就选最便宜的了,这里的抢占式实例测试完可以直接释放) 选择centos7.6镜像 点击下一步:网络和安全组 接下来选中开通h...

祖达
昨天
2
0
【阴阳师】真蛇10层记录

蛇切黑体系 追月神 散件一速,速度越高越好(220+) 镰鼬 招财二速,速度211以上; 山兔 火灵三速,速度180-200均可; 丑女 心眼四速,速度170左右即可; 大蛇 蚌精暴击套。速度高于阴阳师即...

Areya
昨天
5
0
js动态设置元素高度

this.$refs.xxx.style.height= this.contentHeight; 元素需要绑定

Carbenson
昨天
3
0
今天的学习

今天学到了ci框架中的查询语句的where条件语句: 1、$this->db->select('')->from('')->where('id = ??')->get()->result_array();2、$this->db->select('')->from('')->where('id', '??'......

墨冥
昨天
2
0
MySQL在高并发下的订单撮合、系统使用、共享锁与排他锁保证数据一致性

前序 距离上次择文发表,两月余久。2018年也即将要结束了,目前的工作依然是与区块链应用相关的,也很荣幸在9月初受邀签约出版暂名为《区块链以太坊DApp实战开发》一书,预计在明年年初出版。...

我最喜欢三大框架
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部