二叉樹的遍歷實現

echo_dump發表於2020-01-05

二叉樹

  • tree 如圖所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳
在這裡插入圖片描述

  1. 根節點 root節點(所有節點由它開始,它沒有父節點,只有孩子節點)

  2. 節點的度:節點擁有子樹的個數

  3. 樹的度:一棵樹中所有節點的度的最大值

  4. 葉子節點:度為0的節點,沒有子樹的節點,終端節點(A,D,F,G)

  5. 分支節點:度不為0的節點,非終端節點(D,C,E)

  6. 兄弟節點:擁有同一個父節點的節點(D和E,以及F和G都是兄弟節點。。。)

  7. 堂兄弟節點:父節點在同一層的節點(H和D稱為堂兄弟節點)

  8. 孩子節點:一個節點的直接後繼稱為該節點的孩子節點(B,C都是Root的孩子節點。。。)

  9. 雙親節點:一個節點的直接前驅稱為該節點的雙親節點(B的雙親節點就是Root,H的雙親節點是B。。。)

  10. 祖先節點,從根節點到當前節點的所有節點都是該節點的祖先(Root->C->E都是G的祖先)

  11. 子孫節點,當前節點的以後所有節點都是當前節點的子孫(C的子孫,D,E,F,G)

  12. 節點的層次:從根節點開始為1,根的直接後繼節點為2,依次類推(root->1;C->2;E->3;F->4)

  13. 樹的高度:樹中所有節點的層次的最大值(4)

  • 二叉樹特點
  1. 每個節點只能有左子節點和由子節點(節點的最大度 <= 2)

  2. 每個節點最多隻能有兩個子節點

  3. 滿二叉樹:所有的子節點都在最後一層,並且節點的總數等於二的n次方減一,n為層數。如圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳
在這裡插入圖片描述

  1. 完全二叉樹:所有的葉子節點都在最後一層或者倒數第二層,而最後一層的葉子節點在左邊連續,倒數第二層的葉子節點在右邊連續

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳
在這裡插入圖片描述

  • 前序遍歷:先輸出父節點(root節點),再輸出左子樹,再輸出右子樹

  • 中序遍歷:先輸出當前節點的左子樹,再輸出當前節點(父節點),最後輸出右子樹

  • 後續遍歷:先輸出當前節點的左子樹,再輸出當前節點的右子樹,再輸出當前節點(父節點)

  • 具體實現:

<?php

class Node
{
    private $id;

    private $name;

    private $left = null;

    private $right = null;

    public function __construct($id, $name)
    {
        $this->id = $id;
        $this->name = $name;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function setLeft($left)
    {
        $this->left = $left;
    }

    public function setRight($right)
    {
        $this->right = $right;
    }

    /**
     * 1.先輸出root節點
     * 2.判斷當前節點的左子節點是否為空,如果不為空,遞迴遍歷
     * 3.判斷當前節點的右子節點是否為空,如果不為空,遞迴遍歷
     * Notes:前序遍歷
     * Name: preorderTree
     * User: LiYi
     * Date: 2020/1/5
     * Time: 19:10
     */
    public function preorderTree()
    {
        echo $this;

        if ($this->left !=  null) {
            $this->left->preorderTree();
        }

        if ($this->right != null) {
            $this->right->preorderTree();
        }
    }

    /**
     * Notes:中序遍歷
     * Name: middleTree
     * User: LiYi
     * Date: 2020/1/5
     * Time: 19:10
     */
    public function middleTree()
    {
        if ($this->left !=  null) {
            $this->left->preorderTree();
        }

        echo $this;

        if ($this->right != null) {
            $this->right->preorderTree();
        }
    }

    /**
     * Notes:後續遍歷
     * Name: postTree
     * User: LiYi
     * Date: 2020/1/5
     * Time: 19:10
     */
    public function postTree()
    {
        if ($this->left !=  null) {
            $this->left->preorderTree();
        }

        if ($this->right != null) {
            $this->right->preorderTree();
        }

        echo $this;
    }

    public function __toString()
    {
        // TODO: Implement __toString() method.
        return sprintf("當前節點是:%d, name是:%s \n", $this->id, $this->name);
    }
}

class TreeNode
{
    private $root = null;

    public function __construct(Node $root = null)
    {
        $this->root = $root;
    }

    public function middleTree()
    {
        if ($this->root != null) {
            $this->root->middleTree();
        } else {
            var_dump('tree is empty');
        }
    }

    public function postTree()
    {
        if ($this->root != null) {
            $this->root->postTree();
        } else {
            var_dump('tree is empty');
        }
    }

    public function preorderTree()
    {
        if ($this->root != null) {
            $this->root->preorderTree();
        } else {
            var_dump('tree is empty');
        }
    }
}

$node1 = new Node(1, 'liyi');
$node2 = new Node(2, 'liyi2');
$node3 = new Node(3, 'liyi3');
$node4 = new Node(4, 'liyi4');
$node2->setLeft($node4);
$node1->setLeft($node2);
$node1->setRight($node3);
$tree = new TreeNode($node1);
var_dump($tree->preorderTree());
var_dump($tree->middleTree());
var_dump($tree->postTree());
本作品採用《CC 協議》,轉載必須註明作者和本文連結

LIYi ---- github地址

相關文章