- 二叉树的基本数据结构
- 使用数组构造二叉树
- 迭代方式实现先序 中序遍历
- 水平遍历
class Btree
{
public $key;
public $left;
public $right;
public function Btree($value=null)
{
$this->key = $value;
$this->flag=0;
if ($value == null) {
$this->left = null;
$this->right = null;
} else {
$this->left = new Btree();
$this->right = new Btree();
}
}
public function setleft($bt2)
{
$this->left=$bt2;
}
public function setright($bt2)
{
$this->right=$bt2;
}
public function setKey($key) {
$this->key=$key;
}
function pretra()
{
if( $this->key==null) return ;
echo $this->key;
if($this->left!=null) $this->left->pretra();
if($this->right!=null) $this->right->pretra();
}
function ortra()
{
if( $this->key==null) return ;
if($this->left!=null) $this->left->pretra();
echo $this->key;
if($this->right!=null) $this->right->pretra();
}
function potra()
{
if( $this->key==null) return ;
if($this->left!=null) $this->left->pretra();
if($this->right!=null) $this->right->pretra();
echo $this->key;
}
}
- 使用数组构造二叉树---水平遍历BFS使用队存储节点
数组 {3,9,20,#,#,15,7},构造二叉树
3
/ \
9 20
/ \
15 7
function create($bt,$arr)
{
$qu=new queque();
$qu->push($bt);
$n=count($arr);
$i=0;
while($i<$n) {
$p=$qu->pop();
if($arr[$i]=='#'){
$i++;
continue;
}
$p->key=$arr[$i];
$p->left=new Btree();
$qu->push($p->left);
$p->right=new Btree();
$qu->push($p->right);
$i++;
}
}
$bt =new Btree();
$arr=array(3,9,20,'#','#',15,16);
create($bt,$arr);
2 给一个数组,要求建立二叉树的深度最低
function create3($bt,$arr,$begin,$end)
{
if($begin>$end) return null;
$mid=$begin+intval(($end-$begin)/2);
$bt->key=$arr[$mid];
$bt->left=new Btree();
create3($bt->left,$arr,$begin,$mid-1);
$bt->right=new Btree();
create3($bt->right,$arr,$mid+1,$end);
}
3 迭代方式实现先序 中序遍历
非递归的中序和先序遍历方法相同。但是后序遍历,要栈不仅保存树指针的位置,还要有是否访问过其右子树
先序---采用栈
function pretran($bt)
{
echo "herw";
$st=new Stack();
$p=$bt;
while($p!=null||(false===$st->isEmpty()))//注意一定要(false===$st->isEmpty())有外括号
{
if($p!=null){
echo $p->key;
$st->push($p);
$p=$p->left;
}else{
$p=$st->pop();
$p=$p->right;
}
}
}
中序遍历
function ortran($bt)
{
echo "herw";
$st=new Stack();
$p=$bt;
while($p!=null||(false===$st->isEmpty())){
if($p!=null){
//echo $p->key;
$st->push($p);
$p=$p->left;
}else{
$p=$st->pop();
echo $p->key;
$p=$p->right;
}
}
}
后序遍历,还要记录每个节点访问的次数,当访问过一次其flag加1,访问次数为2次的表示左右子树已经访问过,则出栈。为1表示左子树已经访问过,右字数没有访问过。
function postorder($bt)
{
$st=array();
$p=$bt;
while(($n=count($st))||$p!=null){
while($p!=null){
$p->setflag();
$st[]=$p;
$p=$p->left;
}
$p=$st[count($st)-1];
if($p->flag==1){
$p->setflag();
$p=$p->right;
}else if($p->flag==2){
echo $p->key;
array_pop($st);
$p=null;
}
}
}
水平遍历