php二叉樹與赫夫曼樹

科技小能手發表於2017-11-12

在學習圖之前,中間休息了兩天,感覺二叉樹需要消化一下。所以中間去溫習了下sql,推薦一本工具書《程式設計師的SQL金典》看名字不像一本好書,但是作為一個不錯的SQL工具書還是可以小小備忘一下。涵蓋內容不詳細但是挺廣,覆蓋多種主流資料庫


言歸正傳,以前知道折半查詢,二叉樹的概念也是感覺挺有意思,二叉樹的實現有一個案例很不錯,程式碼如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class BiNode{
    public $data;
    public $lchild;
    public $rchild;
    public function __construct($data){
            $this->data = $data;//節點資料
            $this->lchild = null;//左子節點指標
            $this->rchild = null;//右指標
    }
}
class LinkBiTree{
    private $root//根節點
        private static $count;    //結點總數
    const MAX_LEVEL = 2;
     
    public function __construct(){
        $this->root = null;
        self::$count = 0;
    }
 
    public function ClearBiTree(){
        $this->clearTree($this->root);
    }
 
    /**
    *@param $root 樹的根節點
    *
    */
 
    public function clearTree($root){
        if($root){
            if($root->lchild){
                $this->clearTree($root->lchild);
            }
            if($root->rchild){
                $this->clearTree($root->rchild);
            }
            unset($root);
            $root=null;
        }
    }
     
     
}  

其實我更加感興趣的就是赫夫曼樹,能夠給我帶來感覺得才讓我激動,就是100以內猜七次肯定可以猜出來,這種感覺是很奇妙的,當年赫夫曼為了傳輸點卯,更改了資料的排列順序,形成了新的儲存序列和標識,是的竟成使用的字母快速找出來,節省了資源,很棒。


赫爾曼構造演算法的實現

初始化HT

輸入初始n個葉子結點:置HT[1…n]的weight值

然後根據權值來重新安排葉子結點,可以先序可以中序可以後續也可以中序,只要距離根節點的搜尋順序在前面就好

  1. 先序遞迴實現如下


  2. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function PreOrderTraverse(){
    $this->preTraverse($this->root);
    return self::$preArr;
    }
    //還是遞迴呼叫,不對,
    private function preTraverse(){
    if($root){
    self::$preArr[]=$root->data;
    //這裡可以把資料都存進去也可以做其他操作或者業務邏輯function()
    $this->preTraverse($root->lchild);
    $this->preTraverse($root->rchild);
    }
    }
  3. 中序遞迴實現如下

  4. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public function InOrderTraverse(){
    $this->inTraverse($this->root);
    return self::$inArr;
    }
    private function inTraverse(){
    if($root){
    $this->inTraverse($root->lchild);
    self::$inArr[]=$root->data;
    //這裡可以把資料都存進去也可以做其他操作或者業務邏輯function()
    $this->inTraverse($root->rchild);
    }
    }
  5. 後續遞迴實現如下

  6. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function PostOrderTraverse(){
            $this->postTraverse($this->root);
            return self::$postArr;
        }
        private function postTraverse(){
            if($root){
                $this->postTraverse($root->lchild);
                self::$postArr[]=$root->data;
                //這裡可以把資料都存進去也可以做其他操作或者業務邏輯function()
                 
                $this->postTraverse($root->rchild);
            }
        }
  7. 層序遞迴實現如下

  8. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //我個人還是挺喜歡層序遍歷
        public function LevelOrderTraverse(){
            for($i=1;$i<=$this->BiTreeDepth();$i++){
                $this->LevelOrderTraverse($this->root,$i);
            }
            return self::$levelArr;
        }
        private function leverTraverse($root,$level){
            if($root){
                if($level==1){
                    self::$levelArr[]=$root->data;
                }
                $this->LevelOrderTraverse($root->lchild,$level-1);
                $this->LevelOrderTraverse($root->rchild,$level-1);
            }
        }

記錄一下。其實有時候在想,寫程式的同事,真的要做點其他的。但行好事,莫問前程


願法界眾生,皆得安樂。

本文轉自 jackdongting 51CTO部落格,原文連結:http://blog.51cto.com/10725691/1951446


相關文章