php數(shù)據(jù)結(jié)構(gòu)運(yùn)用(樹(shù))

樹(shù)

樹(shù)
  • 樹(shù)是一種數(shù)據(jù)結(jié)構(gòu)认境,它是由n個(gè)有限節(jié)點(diǎn)組成一個(gè)具有層次關(guān)系的集合

  • 樹(shù)的特點(diǎn):

    • 每個(gè)節(jié)點(diǎn)有零個(gè)或多個(gè)子節(jié)點(diǎn)

    • 沒(méi)有父節(jié)點(diǎn)的節(jié)點(diǎn)稱(chēng)為根節(jié)點(diǎn)

    • 每一個(gè)非根節(jié)點(diǎn)有且只有一個(gè)父節(jié)點(diǎn)

    • 除了根節(jié)點(diǎn)外鞭盟,每個(gè)子節(jié)點(diǎn)可以分為多個(gè)不相交的子樹(shù)


二叉樹(shù)

概念

二叉樹(shù)
  • 二叉樹(shù)是樹(shù)的特殊一種减细,具有如下特點(diǎn):

    • 每個(gè)結(jié)點(diǎn)最多有兩顆子樹(shù)单寂,結(jié)點(diǎn)的度最大為2

    • 左子樹(shù)和右子樹(shù)是有順序的,次序不能顛倒

    • 即使某結(jié)點(diǎn)只有一個(gè)子樹(shù),也要區(qū)分左右子樹(shù)

  • 二叉樹(shù)是一種有用的折中方案,既有鏈表的好處雀扶,也有數(shù)組的好處

  • 添加,刪除元素都很快肆汹,并且在查找方面也有很多的算法優(yōu)化

代碼示例:

    class TreeNode{
        public $value = null;
        
        public $right = null;
        
        public $left = null;
        
        function __construct($value) {
            $this->value = $value;
        }
    }

二叉樹(shù)遍歷算法:

前置遍歷(根——>左——>右)

function preTraverse(TreeNode $node) {
    if(!$node) {
        return;
    }
    $this->visit($node->value);
    $this->preTraverse($node->left);
    $this->preTraverse($node->right);
}

中區(qū)遍歷(左——>根——>右)

function midTraverse(TreeNode $node) {
    if(!$node) {
        return;
    }
    $this->midTraverse($node->left);
    $this->visit($node->value);
    $this->midTraverse($node->right);
}

后置遍歷(左——>右——>根)

function sufTraverse(TreeNode $node) {
    if(!$node) {
        return;
    }
    $this->sufTraverse($node->left);
    $this->sufTraverse($node->right);
    $this->visit($node->value);
}

層次遍歷

function levelTraverse(TreeNode $node) {
    $queue = [$node];
    while (!empty($queue)) {
        $temp = array_pop($queue);
        $this->visit($temp);
        if($temp->left) {
            array_push($queue, $temp->left);
        }
        if($temp->right) {
            array_push($queue, $temp->right);
        }
    }
}

滿二叉樹(shù)

高度為h愚墓,由2^h-1個(gè)節(jié)點(diǎn)構(gòu)成的二叉樹(shù)稱(chēng)為滿二叉樹(shù)

滿二叉樹(shù)

完全二叉樹(shù)

完全二叉樹(shù)是由滿二叉樹(shù)而引出來(lái)的,若設(shè)二叉樹(shù)的深度為h昂勉,除第 h 層外浪册,其它各層 (1~h-1) 的結(jié)點(diǎn)數(shù)都達(dá)到最大個(gè)數(shù)(即1~h-1層為一個(gè)滿二叉樹(shù)),第 h 層所有的結(jié)點(diǎn)都連續(xù)集中在最左邊岗照,這就是完全二叉樹(shù)村象。注:左右兩邊沒(méi)有大小關(guān)系。

堆一般都是用完全二叉樹(shù)來(lái)實(shí)現(xiàn)的

完全二叉樹(shù)

二叉查找樹(shù)

  • 沒(méi)有鍵值相等的節(jié)點(diǎn)

  • 若左子樹(shù)不為空攒至,左子樹(shù)上節(jié)點(diǎn)值均小于根節(jié)點(diǎn)的值

  • 若右子樹(shù)不為空厚者,右子樹(shù)上節(jié)點(diǎn)值均大于根節(jié)點(diǎn)的值

二叉查找樹(shù)查找算法

  • 步驟:

    1、若根結(jié)點(diǎn)的關(guān)鍵字值等于查找的關(guān)鍵字迫吐,成功库菲。
    2、否則志膀,若小于根結(jié)點(diǎn)的關(guān)鍵字值熙宇,遞歸查左子樹(shù)鳖擒。
    3、若大于根結(jié)點(diǎn)的關(guān)鍵字值烫止,遞歸查右子樹(shù)蒋荚。
    4、若子樹(shù)為空馆蠕,查找不成功期升。

    public function find(int $data) {
        $p = $this->tree;
        while ($p) {
             if ($data < $p->data) {
                 $p = $p->left;
             } elseif ($data > $p->data) {
                 $p = $p->right;
             } else {
                 return $p;
            }
        }
        return null;
    }

二叉查找樹(shù)插入算法

  • 步驟:

    1、首先執(zhí)行查找算法荆几,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)吓妆。
    2、判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左吨铸、右兒子行拢。將被插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。
    3诞吱、若二叉樹(shù)為空舟奠。則首先單獨(dú)生成根結(jié)點(diǎn)。

    public function insert(int $data) {
        if (!$this->tree) {
            $this->tree = new TreeNode($data);
            return true;
        }
        $p = $this->tree;
        while ($p) {
            if ($data < $p->data) {
                if(!$p->left){
                    $p->left = new TreeNode($data);
                    return true;
                }
                $p = $p->left;
            } elseif ($data > $p->data) {
                if(!$p->right){
                    $p->right = new TreeNode($data);
                    return true;
                }
                $p = $p->right;
            } else {
                return false;
            }
        }
    }

平衡二叉樹(shù)

  • 它的左右兩個(gè)子樹(shù)的高度差的絕對(duì)值不超過(guò)1

  • 并且左右兩個(gè)子樹(shù)都是一棵平衡二叉樹(shù)

平衡二叉查找樹(shù)

  • 既是一顆二叉查找樹(shù)又是一顆平衡二叉樹(shù)

B樹(shù)

B 樹(shù)
  • 平衡的多叉樹(shù)

  • 根節(jié)點(diǎn)至少有兩個(gè)子節(jié)點(diǎn)(可以多個(gè))

  • 每個(gè)節(jié)點(diǎn)有M-1個(gè)key房维,并且以升序排列

  • 位于M-1和M key的子節(jié)點(diǎn)的值位于M-1 和M key對(duì)應(yīng)的Value之間

  • 其它節(jié)點(diǎn)至少有M/2個(gè)子節(jié)點(diǎn)

  • 所有的葉子結(jié)點(diǎn)都位于同一層


B+樹(shù)

與B樹(shù)的區(qū)別:

  • B樹(shù)每個(gè)節(jié)點(diǎn)都存儲(chǔ)key和data沼瘫,所有節(jié)點(diǎn)組成這棵樹(shù),并且葉子節(jié)點(diǎn)指針為null咙俩。

    B Tree
  • B+樹(shù)只有葉子節(jié)點(diǎn)存儲(chǔ)data耿戚,非葉子節(jié)點(diǎn)存儲(chǔ)指針,葉子節(jié)點(diǎn)包含了這棵樹(shù)的所有鍵值阿趁,葉子節(jié)點(diǎn)不存儲(chǔ)指針膜蛔。

    B+Tree
  • 應(yīng)用場(chǎng)景:mysql索引

    為什么mysql用B+樹(shù):B+樹(shù)的非葉子節(jié)點(diǎn)存儲(chǔ)的是指針,相對(duì)與B樹(shù)更小脖阵,如果把所有同一內(nèi)部節(jié)點(diǎn)的關(guān)鍵字存放在同一盤(pán)塊中(分頁(yè)存儲(chǔ))皂股,那么盤(pán)塊所能容納的關(guān)鍵字?jǐn)?shù)量也越多,一次性讀入內(nèi)存的需要查找的關(guān)鍵字也就越多命黔,查詢效率更高呜呐;


紅黑樹(shù)

  • 圖示:

    紅黑樹(shù)
  • 一種自平衡二叉查找樹(shù)
  • 節(jié)點(diǎn)是紅色或黑色
  • 根節(jié)點(diǎn)是黑色
  • 每個(gè)紅色節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)都是黑色
  • 從任一節(jié)點(diǎn)到其每個(gè)葉子的所有路徑都包含相同數(shù)目的黑色節(jié)點(diǎn)
  • 三種操作:左旋、右旋和變色
  • 使用場(chǎng)景:java中的TreeSet,TreeMap悍募,廣泛用在C++的STL中蘑辑。如map和set都是用紅黑樹(shù)實(shí)現(xiàn)的

字典樹(shù)

  • 圖示

    字典樹(shù)
  • 用于統(tǒng)計(jì),排序和保存大量的字符串坠宴,經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計(jì)
  • 利用字符串的公共前綴來(lái)減少查詢時(shí)間以躯,最大限度地減少無(wú)謂的字符串比較,查詢效率比哈希樹(shù)高
  • 應(yīng)用場(chǎng)景:搜索引擎,用在統(tǒng)計(jì)和排序大量字符串忧设,如自動(dòng)機(jī)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市颠通,隨后出現(xiàn)的幾起案子址晕,更是在濱河造成了極大的恐慌,老刑警劉巖顿锰,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谨垃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡硼控,警方通過(guò)查閱死者的電腦和手機(jī)刘陶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牢撼,“玉大人匙隔,你說(shuō)我怎么就攤上這事⊙妫” “怎么了纷责?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)撼短。 經(jīng)常有香客問(wèn)我再膳,道長(zhǎng),這世上最難降的妖魔是什么曲横? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任喂柒,我火速辦了婚禮,結(jié)果婚禮上禾嫉,老公的妹妹穿的比我還像新娘灾杰。我一直安慰自己,他們只是感情好夭织,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布吭露。 她就那樣靜靜地躺著,像睡著了一般尊惰。 火紅的嫁衣襯著肌膚如雪讲竿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天弄屡,我揣著相機(jī)與錄音题禀,去河邊找鬼。 笑死膀捷,一個(gè)胖子當(dāng)著我的面吹牛迈嘹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼秀仲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼融痛!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起神僵,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤雁刷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后保礼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體沛励,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年炮障,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了目派。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胁赢,死狀恐怖企蹭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情徘键,我是刑警寧澤练对,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站吹害,受9級(jí)特大地震影響螟凭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜它呀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一螺男、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纵穿,春花似錦下隧、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至句惯,卻和暖如春土辩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抢野。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工拷淘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人指孤。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓启涯,卻偏偏與公主長(zhǎng)得像贬堵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子结洼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 目錄 1黎做、什么是樹(shù) 2、相關(guān)術(shù)語(yǔ) 3补君、二叉樹(shù) 3.1引几、二叉樹(shù)的類(lèi)型 3.2、二叉樹(shù)的性質(zhì) 3.3挽铁、二叉樹(shù)的結(jié)構(gòu) 3...
    我哈啊哈啊哈閱讀 2,564評(píng)論 0 10
  • 樹(shù)是非線性存儲(chǔ)結(jié)構(gòu),存儲(chǔ)的是具有“一對(duì)多”關(guān)系的數(shù)據(jù)元素的集合敞掘。 使用樹(shù)結(jié)構(gòu)存儲(chǔ)的集合 {A,B,C,D,E,F,...
    飛揚(yáng)code閱讀 4,765評(píng)論 0 2
  • 原文鏈接 B樹(shù) 1.前言: 動(dòng)態(tài)查找樹(shù)主要有:二叉查找樹(shù)(Binary Search Tree)叽掘,平衡二叉查找樹(shù)(...
    非典型程序員閱讀 1,164評(píng)論 0 3
  • B樹(shù) 1.前言: 動(dòng)態(tài)查找樹(shù)主要有:二叉查找樹(shù)(Binary Search Tree),平衡二叉查找樹(shù)(Balan...
    鐵甲依然在_978f閱讀 1,447評(píng)論 0 4
  • 目錄 0.樹(shù)0.1 一般樹(shù)的定義0.2 二叉樹(shù)的定義 1.查找樹(shù)ADT 2.查找樹(shù)的實(shí)現(xiàn)2.1 二叉查找樹(shù)2.2 ...
    王偵閱讀 7,245評(píng)論 0 3