二叉樹數據結構及其遍歷

1、二叉樹的定義及相關知識點php

  1.定義:再計算機科學中,二叉樹是每一個結點最多有兩個子樹的樹結構,且二叉樹的子樹有左右之分,順序不能任意顛倒;node

  2.性質:數據結構

    a.若是二叉樹的根節點層次從0開始,那麼第i層樹的節點爲 2i 個節點;學習

    b.高度爲k的一個二叉樹,那麼它的結點node至多有2k-1個結點(k>=1,這裏注意了有些博客以及維基百科中是k>=0,從0開始的,因此高度爲K的二叉樹節點之多爲2(k+1)-1個結點);this

    c.對任何一棵二叉樹,若是其葉子結點(度爲0)數爲m, 度爲2的結點數爲n, 則m = n + 1(這一條不太理解,待學習)。spa

  3.完美二叉樹(滿二叉樹):深度爲K(K>=1)的一個二叉樹,其結點有2k-1個結點,則該二叉樹爲完美二叉樹;code

    

  4.徹底二叉樹:從根結點到倒數第二層,知足完美二叉樹(滿二叉樹),最後一層能夠不徹底填充,可是必須按照從左到右的順序,其葉子結點都靠左對齊;對象

  

  5.完滿二叉樹blog

  未完待續......博客

2、二叉樹的遍歷

<?php
class Node{
    public $value = Null;
    public $child_left = Null;
    public $child_right = Null;

    function __construct($value)
    {
        if(!is_null($value) || !empty($value))
            $this->value = $value;
    }

    /***
     * 建立$this->>value的左右子樹節點
     * @param $left
     * @param $right
     *
     */
    public function createNodeLrChild(Node $left=Null, Node $right=Null)
    {
        if(is_null($this->value) || empty($this->value))
            return false;
        if(!is_null($left) && !empty($left))
            $this->child_left = $left;
        if(!is_null($right) && !empty($right))
            $this->child_right = $right;
    }
}

final class Ergodic{
    /***
     * 先序遍歷:先從根節點、再左子樹、再右子樹;在遍歷左右子樹的時候,仍然須要先從根節點開始遍歷,再遍歷左子樹,再遍歷右子樹
     * @param $root
     */
    public static function preOrder($root)
    {
        #  定義一個棧
        $stack = array();
        array_push($stack, $root);

        # 循環取出節點的左右子樹並壓入棧中,再取出
        while(!empty($stack))
        {
            // 彈出一個節點,並輸出節點的值
            $center_order = array_pop($stack);
            echo $center_order->value.' ';

            // 取出左右子樹節點,並壓去棧中(注意順序:先序遍歷是根節點、左子樹、右子樹;因此應該先壓入右子樹節點,先進後出)
            if(!empty($center_order->child_right) && !is_null($center_order->child_right))
                array_push($stack, $center_order->child_right);
            if(!empty($center_order->child_left) && !is_null($center_order->child_left))
                array_push($stack, $center_order->child_left);
        }
    }

    /***
     * 中序遍歷:先左子樹、再根節點、再右子樹;
     * @param $root
     */
    public static function midOrder($root)
    {
        $stack = array();
        $center_order = $root;
        while(!empty($stack) || !empty($center_order) || $center_order !=null)
        {
            while($center_order !=null)
            {
                var_dump($center_order); // 輸出該信息,有助於理解遍歷的過程
                array_push($stack, $center_order);
                $center_order = $center_order->child_left; // 一直查找節點的左子樹節點(是否有值,若是沒有,則退出循環)
            }

            $center_order = array_pop($stack); // 而後彈出該節點的對象,獲取該節點的值
            echo $center_order->value.' ';// 輸出該值
            $center_order = $center_order->child_right; // 而後再獲取該節點的右子樹的值(看看是否存在左子樹等)
        }
    }

    /***
     * 後序遍歷
     * @param $roots
     */
    public static function endOrder($root)
    {
        $stack = array();
        $visit_stack = array();
        array_push($stack, $root);
        while(!empty($stack))
        {
            $center_order = array_pop($stack);
            array_push($visit_stack, $center_order);
            if($center_order->child_left != null)
                array_push($stack, $center_order->child_left);
            if($center_order->child_right != null)
                array_push($stack, $center_order->child_right);
        }

        while(!empty($visit_stack))
        {
            $center_order = array_pop($visit_stack);
            echo $center_order->value.' ';
        }
    }
}

# 建立二叉樹數據結構
$a = new Node('A');
$b = new Node('B');
$c = new Node('C');
$d = new Node('D');
$e = new Node('E');
$f = new Node('F');
$g = new Node('G');
$h = new Node('H');
$i = new Node('I');

# 添加節點的左右子節點
$a->createNodeLrChild($b, $c);
$b->createNodeLrChild($d, $g);
$c->createNodeLrChild($e, $f);
$d->createNodeLrChild($h, $i);

# 先序遍歷
//Ergodic::preOrder($a);
//echo "\n";
//Ergodic::midOrder($a);
//echo "\n";
//Ergodic::endOrder($a);
相關文章
相關標籤/搜索