<?php
/**
* @desc
* 树
* 定义:树是n(n>0)个结点的有限集。n=0时,称为空树。在任意一棵非空树中:
* 1. 有且仅有一个特定的称为根的结点。
* 2. 当n>1时,其余结点可分为(m>0)个互不相交的有限集合 T1,T2,....Tm,其中每
* 一个集合本身又是一棵树,并且称为根的子树。
* 子结点的定义:
* 1. n>0时,根结点是唯一的,不可能有多个。数据结构中的数只有一个根结点。
* 2. m>0时,子数的个数没有限制,但它们一定是互不相交的。
* 结点分类:
* 1. 树的结点包含一个数据无数及若干指向子树的分支。结点拥有的子树称为结点的度。
* 度为0的结点称为叶结点或终端结点。度不为0的结点称为非终端结点或分支结点。除
* 根结点外,分支结点称为内部结点。树的度是树内各结点的度的最大值。
* 结结构:
* +++++++++++++++++++++++++++++++++++++++++++
* + A-->根结点 +
* + / \ +
* + 结点度为1<-- B C-->结点度为2 +
* + / / \ +
* +结点度为3<-- D E F +
* + / | \ \ +
* + G H I J-->结点度为0 +
* +++++++++++++++++++++++++++++++++++++++++++
* + 该树结点的度最大度是结点D的度,所以树的度也为3 +
* +++++++++++++++++++++++++++++++++++++++++++
*
* 结点间的关系:
* 结点的子树称为该结点的孩子(Child)
* 结点称为子构的双亲(Parent)
* 同一个结点下的孩子之间称为兄弟(slibing)
* 结点的祖先是从根到该结点所经分支上的所有结点(H结点的祖先是:DBA,B结点的子孙是D,G,H,I)
* 树的其他相关概念:
* 结点的层次从根开动员定义,根为第一层,根的子为二层,若某结点在n层,则子结点在n+1层。
* 双亲在同一层的结点称为堂兄弟。DEF为堂兄弟,GHIJ也是
* 树的最层次称为数据的尝试或高度,当前树的尝试为 4
* 如果将树中结点的各子树看成从左到右是有次序的,不能互换,刚称该树为有序树,否则称为无序树。
* 森林(Forest)是m(m>=0)棵互不相交的树的集合。对于每个结点而言,其子树的集合即为森林。
*
* +++++++++++++++++++++++++++++++++++++++++++++
* + 线性结构 树结构 +
* +.第一个数据元素,无前驱 .根结点,无双亲,唯一 +
* +.最后一个数据元素:无后继 .叶结点无孩子,可以多个 +
* +.中间无素,一个前驱一个后继 .中间结点,一个双亲多个孩子 +
* +++++++++++++++++++++++++++++++++++++++++++++
*
* 树的存储结构:
* 无论按何种顺序将树中所有结点存储到数组中,结点的存储位置都无法直接反应逻辑关系。
* 简单垢顺序存储无法满足树的实现要求。可以充分利分顺序与链式结构的特点,可以实现对树的存储结构的表示:
* 1. 双亲表示法
* 除了根结点外的每一个结点,它不一定有孩子,但一定有双亲。data:存数据 parent:双新(父结点) |
* 根结点没有双亲,parent 设为-1, 所有结点都存储有双亲的位置
* 找父结点时间复杂度O(1),找子点遍历0(n);
* 改进: 1.增加长子域,就可以很容易得到结点的孩子。如没有孩子的结点,长子域高为-1
* 2.增加右兄弟域,来体现兄弟关系。如果存在就记下位置,不存在记录-1
*
* 2. 孩子表示法
* 每个结点可能有多个子树,考虑用多重链表,每个结点有多个指针域,每个指针指向子树的根结点(多重链表表示法)
*
* 3. 孩子兄弟法
*
* 存储结构的设计是一个非常灵活的过程,设计是否合理,取决于基于该存储结构的运算是否适合,方便,时间复杂度好不好。
* @author RanPing 2012-08-27
*/
class Tree {
var $nodes;
var $root, $number;
function initTree(){
}
function destoryTree(){
}
function createTree($defition){
}
function clearTree(){
}
function treeEmpty(){
}
function treeDepth(){
}
function root(){
}
function value($current){
}
function assign($current, $value){
}
function parent($current){
}
function leftChild($current){
}
function rightSibling($current){
}
function insertChild($p, $i, $c){
}
function deleteChild($p, $i){
}
}
class TNode {
var $data;
var $parent;
}
/**
* @desc
* 二叉树
* 定义:树是n(n>0)个结点的有限集, n=0时,称为空二叉树。或者由一根结点和两棵互不相交的,分别称为左子树、右子树的二叉树组成。
* 结构:
* +++++++++++++++++++++++++++++++++++++++++++
* + 50 +
* + / \ +
* + 25 75 +
* + / \ / \ +
* + 12 37 62 88 +
* + /\ / \ / \ / \ +
* + 6 18 31 43 56 68 82 96 +
* +++++++++++++++++++++++++++++++++++++++++++
* + +
* +++++++++++++++++++++++++++++++++++++++++++
* 特点:
* 1. 每棵树最多有两棵子树,所以不存在度数大于2的结点,不是只有两棵子树,是最多有2棵。没有与有1棵都是允许的。
* 2. 左子树和右子树是有顺序的。不能随意颠倒。
* 3. 即使只有一棵子树,也要区分是左还是右子树。
*
* 二叉树的五种基本形态:
* 1. 空二叉数
* 2. 只有一个根结点
* 3. 根结点只有左子树
* 4. 根结点只有右子树
* 5. 根结点既有左,也有右子树
*
* 特殊二叉树:
* 1.斜树,只有左子树(左斜树),或者只有右子树(右斜树)。线性表可以理解成是树的一种特殊的表现形式。
*
* 2.满二叉树,在一棵二叉树中,如果所有分支结点都存在左子树和右子树,且所有叶子都在同一层上为满二叉树。(上图二叉树即满二叉树)
* 特点:1.叶子只出现在都后一层。
* 2.叶子结点的度一定是2。
* 3.在同样深度的二叉数中,满二叉树的结点个数最多,叶子数最多。
* 3.完全二叉树:
* 定义:(满二叉树是完全二叉树,但完全二叉树不一定是满二叉树)
* 对一棵具有n个结点的二叉树层序编号,如果编号为i(1<i<n)的结点与同样深度的满二叉数中编号为i的结点在树中的
* 校园相同,则这棵二叉树称为完全二叉数。
* 特点:
* 1. 叶子结点只出现在最下二层。
* 2. 最下层的叶子一定集中在左部连续位置。
* 3. 倒数二层,如果有子结点,一定都在右部的连续位置。
* 4. 如果结点度为1,则该该结点只有左孩子,不存在只有右子树的情况。
* 5. 同样结点的二叉树,完全二叉树的深度最小。
* 判断二叉树是不是完全二叉树的办法就是:每个结点按照满二叉树进行顺序编号,如果编号出现空档,则说明不是完全二叉树,反之则是。
*
* 二叉树的性质:
* 性质1:在二叉数的i层上至多有2的i-1次方个结点。1,2,4,8
* 性质2:深度为k的二叉树至多有2的k-1次方个结点。1+2+4+8 4层 2的4次方=16-1
* 性质3:任一二叉树,终端结点数(叶子结点数)为No,度为2的结点数为N2,则No=N2+1。
* T树结点=N0+N1+N2
* 分支线总数=n(总结点数)-1 = n1(只有一个叶结点的结点数) + 2n2(二个叶结点的结点数)
* N0+N1+N2 - 1 = n1(只有一个叶结点的结点数) + 2n2(二个叶结点的结点数);
*
* 性质4:具有n个结点的完全二叉树的深度是log2的n次幂+1
* 性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号,对任一个结点i(1<=i<=n)有:
* 1. 如果i=1,则结点i是根,无双亲;如果i>1 刚双亲结点是|i/2|
* 2. 如果2i>n,则无左子树;否则左子树的结点是2i
* 3. 如果2i+1>n,刚无右子树,否则右子树结点是2i+1;
*
* 二叉数的存储结构:
* 1.顺序存储结构
* 2.二叉链表(同树)
*
* 遍历二叉树:
* 1. 前序遍历:为空则返回,否则先访问根结点,然后前序遍历左子树,在前序遍历右子树。
* 2. 中序遍历
* 3. 后序遍历
* 4. 层序遍历
*/