二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。
一棵深度为k,且有2^k-1个节点称之为满二叉树;深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树。
 
 
  1. <?php
  2. /**  * 二叉树的定义  */
  3. class BinaryTree {
  4. protected $key = NULL;      //  当前节点的值
  5. protected $left = NULL;     //  左子树
  6. protected $right = NULL;    //  右子树
  7. /**      * 以指定的值构造二叉树,并指定左右子树      *
  8. * @param mixed $key 节点的值.
  9. * @param mixed $left 左子树节点.
  10. * @param mixed $right 右子树节点.
  11. */
  12. public function __construct( $key = NULL, $left = NULL, $right = NULL) {
  13.        $this->key = $key;
  14.         if ($key === NULL) {
  15.             $this->left = NULL;
  16.             $this->right = NULL;
  17.         }
  18.         elseif ($left === NULL) {
  19.             $this->left = new BinaryTree();
  20.             $this->right = new BinaryTree();
  21.         }
  22.         else {
  23.             $this->left = $left;
  24.             $this->right = $right;
  25.         }
  26.     }
  27.  
  28.     /**
  29.      * 析构方法.
  30.      */
  31.     public function __destruct() {
  32.         $this->key = NULL;
  33.         $this->left = NULL;
  34.         $this->right = NULL;
  35.     }
  36.  
  37.     /**
  38.     * 清空二叉树.
  39.     **/
  40.     public function purge () {
  41.         $this->key = NULL;
  42.         $this->left = NULL;
  43.         $this->right = NULL;
  44.     }
  45.  
  46.     /**
  47.      * 测试当前节点是否是叶节点.
  48.      *
  49.      * @return boolean 如果节点非空并且有两个空的子树时为真,否则为假.
  50.      */
  51.     public function isLeaf() {
  52.         return !$this->isEmpty() &&
  53.             $this->left->isEmpty() &&
  54.             $this->right->isEmpty();
  55.     }
  56.  
  57.     /**
  58.      * 测试节点是否为空
  59.      *
  60.      * @return boolean 如果节点为空返回真,否则为假.
  61.      */
  62.     public function isEmpty() {
  63.         return $this->key === NULL;
  64.     }
  65.  
  66.     /**
  67.      * Key getter.
  68.      *
  69.      * @return mixed 节点的值.
  70.      */
  71.     public function getKey() {
  72.         if ($this->isEmpty()) {
  73.             return false;
  74.         }
  75.         return $this->key;
  76.     }
  77.  
  78.     /**
  79.      * 给节点指定Key值,节点必须为空
  80.      *
  81.      * @param mixed $object 添加的Key值.
  82.      */
  83.     public function attachKey($obj) {
  84.         if (!$this->isEmpty())
  85.             return false;
  86.         $this->key = $obj;
  87.         $this->left = new BinaryTree();
  88.         $this->right = new BinaryTree();
  89.     }
  90.  
  91.     /**
  92.      * 删除key值,使得节点为空.
  93.      */
  94.     public function detachKey() {
  95.         if (!$this->isLeaf())
  96.             return false;
  97.         $result = $this->key;
  98.         $this->key = NULL;
  99.         $this->left = NULL;
  100.         $this->right = NULL;
  101.         return $result;
  102.     }
  103.  
  104.     /**
  105.      * 返回左子树
  106.      *
  107.      * @return object BinaryTree 当前节点的左子树.
  108.      */
  109.     public function getLeft() {
  110.         if ($this->isEmpty())
  111.             return false;
  112.         return $this->left;
  113.     }
  114.  
  115.     /**
  116.      * 给当前结点添加左子树
  117.      *
  118.      * @param object BinaryTree $t 给当前节点添加的子树.
  119.      */
  120.     public function attachLeft(BinaryTree $t) {
  121.         if ($this->isEmpty() || !$this->left->isEmpty())
  122.             return false;
  123.         $this->left = $t;
  124.     }
  125.  
  126.     /**
  127.      * 删除左子树
  128.      *
  129.      * @return object BinaryTree  返回删除的左子树.
  130.      */
  131.     public function detachLeft() {
  132.         if ($this->isEmpty())
  133.             return false;
  134.         $result = $this->left;
  135.         $this->left = new BinaryTree();
  136.         return $result;
  137.     }
  138.  
  139.     /**
  140.      * 返回当前节点的右子树
  141.      *
  142.      * @return object BinaryTree 当前节点的右子树.
  143.      */
  144.     public function getRight() {
  145.         if ($this->isEmpty())
  146.             return false;
  147.         return $this->right;
  148.     }
  149.  
  150.     /**
  151.      * 给当前节点添加右子树
  152.      *
  153.      * @param object BinaryTree $t 需要添加的右子树.
  154.      */
  155.     public function attachRight(BinaryTree $t) {
  156.         if ($this->isEmpty() || !$this->right->isEmpty())
  157.             return false;
  158.         $this->right = $t;
  159.     }
  160.  
  161.     /**
  162.      * 删除右子树,并返回此右子树
  163.      * @return object BinaryTree 删除的右子树.
  164.      */
  165.     public function detachRight() {
  166.         if ($this->isEmpty ())
  167.             return false;
  168.         $result = $this->right;
  169.         $this->right = new BinaryTree();
  170.         return $result;
  171.     }
  172.  
  173.     /**
  174.      * 先序遍历
  175.      */
  176.     public function preorderTraversal() {
  177.         if ($this->isEmpty()) {
  178.             return ;
  179.         }
  180.         echo ' ', $this->getKey();
  181.         $this->getLeft()->preorderTraversal();
  182.         $this->getRight()->preorderTraversal();
  183.     }
  184.  
  185.     /**
  186.      * 中序遍历
  187.      */
  188.     public function inorderTraversal() {
  189.         if ($this->isEmpty()) {
  190.             return ;
  191.         }
  192.         $this->getLeft()->preorderTraversal();
  193.         echo ' ', $this->getKey();
  194.         $this->getRight()->preorderTraversal();
  195.     }
  196.  
  197.     /**
  198.      * 后序遍历
  199.      */
  200.     public function postorderTraversal() {
  201.         if ($this->isEmpty()) {
  202.             return ;
  203.         }
  204.         $this->getLeft()->preorderTraversal();
  205.         $this->getRight()->preorderTraversal();
  206.         echo ' ', $this->getKey();
  207.     }
  208. }
  209.  
  210. /**
  211.  * 二叉排序树的PHP实现
  212.  */
  213.  
  214. class BST extends BinaryTree {
  215.   /**
  216.      * 构造空的二叉排序树
  217.      */
  218.     public function __construct() {
  219.         parent::__construct(NULL, NULL, NULL);
  220.     }
  221.  
  222.     /**
  223.      * 析构
  224.      */
  225.     public function __destruct() {
  226.         parent::__destruct();
  227.     }
  228.  
  229.     /**
  230.      * 测试二叉排序树中是否包含参数所指定的值
  231.      *
  232.      * @param mixed $obj 查找的值.
  233.      * @return boolean True 如果存在于二叉排序树中则返回真,否则为假期
  234.      */
  235.     public function contains($obj) {
  236.         if ($this->isEmpty())
  237.             return false;
  238.         $diff = $this->compare($obj);
  239.         if ($diff == 0) {
  240.             return true;
  241.         }elseif ($diff < 0)             return $this->getLeft()->contains($obj);
  242.         else
  243.             return $this->getRight()->contains($obj);
  244.     }
  245.  
  246.     /**
  247.      * 查找二叉排序树中参数所指定的值的位置
  248.      *
  249.      * @param mixed $obj 查找的值.
  250.      * @return boolean True 如果存在则返回包含此值的对象,否则为NULL
  251.      */
  252.     public function find($obj) {
  253.         if ($this->isEmpty())
  254.             return NULL;
  255.         $diff = $this->compare($obj);
  256.         if ($diff == 0)
  257.             return $this->getKey();
  258.         elseif ($diff < 0)             return $this->getLeft()->find($obj);
  259.         else
  260.             return $this->getRight()->find($obj);
  261.     }
  262.  
  263.     /**
  264.      * 返回二叉排序树中的最小值
  265.      * @return mixed 如果存在则返回最小值,否则返回NULL
  266.      */
  267.     public function findMin() {
  268.         if ($this->isEmpty ())
  269.             return NULL;
  270.         elseif ($this->getLeft()->isEmpty())
  271.             return $this->getKey();
  272.         else
  273.             return $this->getLeft()->findMin();
  274.     }
  275.  
  276.     /**
  277.      * 返回二叉排序树中的最大值
  278.      * @return mixed 如果存在则返回最大值,否则返回NULL
  279.      */
  280.     public function findMax() {
  281.         if ($this->isEmpty ())
  282.             return NULL;
  283.         elseif ($this->getRight()->isEmpty())
  284.             return $this->getKey();
  285.         else
  286.             return $this->getRight()->findMax();
  287.     }
  288.  
  289.     /**
  290.      * 给二叉排序树插入指定值
  291.      *
  292.      * @param mixed $obj 需要插入的值.
  293.      * 如果指定的值在树中存在,则返回错误
  294.      */
  295.     public function insert($obj) {
  296.         if ($this->isEmpty()) {
  297.             $this->attachKey($obj);
  298.         } else {
  299.             $diff = $this->compare($obj);
  300.             if ($diff == 0)
  301.                 die('argu error');
  302.             if ($diff < 0)                 $this->getLeft()->insert($obj);
  303.             else
  304.                 $this->getRight()->insert($obj);
  305.         }
  306.         $this->balance();
  307.     }
  308.  
  309.  /**
  310.      * 从二叉排序树中删除指定的值
  311.      *
  312.      * @param mixed $obj 需要删除的值.
  313.      */
  314.     public function delete($obj) {
  315.         if ($this->isEmpty ())
  316.             die();
  317.  
  318.         $diff = $this->compare($obj);
  319.         if ($diff == 0) {
  320.             if (!$this->getLeft()->isEmpty()) {
  321.                 $max = $this->getLeft()->findMax();
  322.                 $this->key = $max;
  323.                 $this->getLeft()->delete($max);
  324.             }
  325.             elseif (!$this->getRight()->isEmpty()) {
  326.                 $min = $this->getRight()->findMin();
  327.                 $this->key = $min;
  328.                 $this->getRight()->delete($min);
  329.             } else
  330.                 $this->detachKey();
  331.         } else if ($diff < 0)                 $this->getLeft()->delete($obj);
  332.             else
  333.                 $this->getRight()->delete($obj);
  334.         $this->balance();
  335.     }
  336.  
  337.     public function compare($obj) {
  338.         return $obj - $this->getKey();
  339.     }
  340.  
  341.     /**
  342.      * Attaches the specified object as the key of this node.
  343.      * The node must be initially empty.
  344.      *
  345.      * @param object IObject $obj The key to attach.
  346.      * @exception IllegalOperationException If this node is not empty.
  347.      */
  348.     public function attachKey($obj) {
  349.         if (!$this->isEmpty())
  350.             return false;
  351.         $this->key = $obj;
  352.         $this->left = new BST();
  353.         $this->right = new BST();
  354.     }
  355.  
  356.     /**
  357.      * Balances this node.
  358.      * Does nothing in this class.
  359.      */
  360.     protected function balance () {}
  361.  
  362.     /**
  363.      * Main program.
  364.      *
  365.      * @param array $args Command-line arguments.
  366.      * @return integer Zero on success; non-zero on failure.
  367.      */
  368.     public static function main($args) {
  369.         printf("BinarySearchTree main program.\n");
  370.         $root = new BST();
  371.         foreach ($args as $row) {
  372.             $root->insert($row);
  373.         }
  374.         return $root;
  375.     }
  376. }
  377.  
  378. $root = BST::main(array(50, 3, 10, 5, 100, 56, 78));
  379. echo $root->findMax();
  380. $root->delete(100);
  381. echo $root->findMax();

  

php二叉树算法的更多相关文章

  1. JavaScript实现二叉树算法

    二叉树的遍历方式 分别为中序遍历(左子树->当前节点->右子树).前序遍历(当前节点->左子树->右子树).后序遍历(左子树->右子树->当前节点).下面使用Jav ...

  2. JS数据结构与算法 - 剑指offer二叉树算法题汇总

    ❗❗ 必看经验 在博主刷题期间,基本上是碰到一道二叉树就不会碰到一道就不会,有时候一个下午都在搞一道题,看别人解题思路就算能看懂,自己写就呵呵了.一气之下不刷了,改而先去把二叉树的基础算法给搞搞懂,然 ...

  3. JS - 二叉树算法实现与遍历 (更新中...)

    一.关于二叉树: 截图来自:https://segmentfault.com/a/1190000000740261 温馨提示:学习以及使用二叉树概念,心中永远有这么一个图,对于理解和接受二叉树有很大的 ...

  4. js 二叉树算法

    //生成二叉树 function binarySearchTree() { let Node = function(key) { this.key = key; this.left = null; t ...

  5. Javascritp 数据结构和二叉树算法

    1,所有圆圈都是一个节点,里面的数字就是节点的值.8上面没有父节点,那么8就是根节点,而4,7,13没有子节点了,称之为叶子结点.其他的称之为:中间结点. 2,8节点是3和10的父节点,3是8的左孩子 ...

  6. 面试常见二叉树算法题集锦-Java实现

    1.求二叉树的深度或者说最大深度 /* ***1.求二叉树的深度或者说最大深度 */ public static int maxDepth(TreeNode root){ if(root==null) ...

  7. C#使用二叉树算法设计一个无限分级的树表

    效果图: 数据库: 操作树的示意图: 控制器代码: using Dw.Business; using Dw.Entity; using Dw.Utilities; using System; usin ...

  8. java版二叉树算法实现

    import java.util.ArrayList; class BinaryTree { private static class TreeNode { int data; TreeNode le ...

  9. [二叉树算法]关于判断是否为BST的算法

    //判断是否为BST 搜索树==二叉排序树 1.递归知最大最小值.2.先中序判是否单调 bool IsValidBST(BTNode *p,int low,int high){ if(p==NULL) ...

随机推荐

  1. 在ACCESS中创建数据库和查询(ACCESS 2000)

    备份还原数据库 备份.还原 —— 复制\粘贴 压缩修复数据库命令 —— 复制该文件并重新组织,并重新组织文件在磁盘上的储存方式.压缩同时优化了Access数据库的性能.(工具——实用数据库工具或者工具 ...

  2. HttpWebRequest代理访问网站

    private void button1_Click(object sender, EventArgs e) { string str ="http://www.7y8.com/V/ip.a ...

  3. js COOKIE 记住帐号或者uuid

    当开始接到这个任务的时候,我对cookie还是没多少了解的,而uuid的生成也是一无所知.但是当你发现这个网址http://stackoverflow.com/questions/105034/how ...

  4. [再寄小读者之数学篇](2014-11-19 $\sin(x+y)=\sin x\cos y+\cos x\sin y$)

    $$\bex \sin(x+y)=\sin x\cos y+\cos x\sin y. \eex$$ Ref. [Proof Without Words: Sine Sum Identity, The ...

  5. HashBiMap

    HashBiMap  AbstractMap类实现了Map接口定义的一些方法,而BiMap类定义了其子类需要实现的一些方法,使得所有实现BiMap的类必须符合其独有的特性:键.值都是唯一的.HashB ...

  6. android操作文件

    Android中读取/写入文件的方法,与Java中的I/O是一样的,提供了openFileInput()和openFileOutput()方法来读取设备上的文件.但是在默认状态下,文件是不能在不同的程 ...

  7. Linux基本命令(10)其他命令

    其他命令 命令 功能 命令 功能 echo 显示一字串 passwd 修改密码 clear 清除显示器 lpr 打印 lpq 查看在打印队列中等待的作业 lprm 取消打印队列中的作业 10.1 ec ...

  8. Python在centos下的安装

    1.wget http://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz默认下载到主目录下 2.tar xzf Python-2.6.6.tgz 3 ...

  9. 算法:最大子数组own

    转载标明出处:http://i.cnblogs.com/EditPosts.aspx?postid=4726782&update=1 暴力法: // maxValue.cpp : 定义控制台应 ...

  10. 封装cookie.js、EventUtil.js、

    最近学习了javascript,封装好的东西看起来舒服,以备需要的时候拉出来,jquery对javascript做了很好的封装!以后会多用jquery多些 var CookieUtil = { get ...