摘要:回來更新一波,最近刷劍指,才又發(fā)現(xiàn)樹真是一個(gè)大頭,二叉樹的題目和變化運(yùn)用好多啊二叉樹算法引子很多人說二叉樹沒什么卵用,我覺得是他的工資和公司讓他跨不過這個(gè)坎還有很多人學(xué)了一些樹的知識(shí),發(fā)現(xiàn)也用不上,我想說的是,讀一本書體現(xiàn)不了這本書
回來更新一波,最近刷《劍指offer》,才又發(fā)現(xiàn)樹真是一個(gè)大頭,二叉樹的題目和變化運(yùn)用好多啊~
/** * PHP二叉樹算法 * Created on 2017-5-6 * Update on 2017-8-10 * Author entner * Email 1185087164@qq.com */引子
????很多人說二叉樹沒什么卵用,我覺得是他的工資和公司讓他跨不過這個(gè)坎;還有很多人學(xué)了一些樹的知識(shí),發(fā)現(xiàn)也用不上,我想說的是,讀一本書體現(xiàn)不了這本書的價(jià)值,要多讀幾本才會(huì)把你和別人的差別體現(xiàn)出來。
????二叉樹是嚴(yán)格定義的,有很好的對(duì)稱性和比較高的數(shù)據(jù)關(guān)聯(lián)度,對(duì)數(shù)據(jù)的存儲(chǔ)和計(jì)算,有很好的演示作用,比如完全二叉樹:
????當(dāng)然,二叉樹更適合鏈表存儲(chǔ),效率更高,總的來說,以二叉樹為基礎(chǔ)我們可以衍生出許多神奇的運(yùn)用,舉幾個(gè)常用的場(chǎng)景為我說的話正言:
編譯器表達(dá)式處理
快速查找與排序
文件壓縮
文件系統(tǒng)管理
游戲場(chǎng)景劃分、監(jiān)測(cè)、渲染
我承認(rèn),上面好多東西你并不會(huì)直接接觸,但是,我們關(guān)鍵是去學(xué)習(xí)一種思維和設(shè)計(jì),退一萬步也可以增加一點(diǎn)見識(shí):)一、二叉樹抽象數(shù)據(jù)類型操作條目
關(guān)于書的操作太多了,我只列一些常用的(這些都是常考的知識(shí)點(diǎn)),有興趣的相信也有技能去淘到“好貨” -InitTree 構(gòu)造空樹 -PreTra 返回樹中某結(jié)點(diǎn)的值 -InTra 給樹中某結(jié)點(diǎn)賦值為value -LevelTra 返回某非根結(jié)點(diǎn)的雙親,否則返回空 -LeftChild 返回某非葉結(jié)點(diǎn)的最左孩子,否則返回空二、默寫二叉樹常用數(shù)據(jù)結(jié)構(gòu)
默寫會(huì)讓你記憶更深刻,同時(shí)也會(huì)鍛煉抽象的邏輯思維,一邊看不懂,就多看幾遍,再查一查相關(guān)資料,應(yīng)該問題不大,你甚至可以找張紙默寫一下。
/** *InitTree 初始化樹 * * Typedef int TElementType //構(gòu)造一個(gè)數(shù)據(jù)類型 Typedef Struct Tree{ //構(gòu)造二叉樹抽象數(shù)據(jù)類型 TElementType data; //聲明一個(gè)數(shù)組,先構(gòu)建一個(gè)樹 Struct Tree *leftChild; //左孩子節(jié)點(diǎn) Struct Tree *rightChild; //右孩子節(jié)點(diǎn) }Tree; */ /** * Value 獲取樹的結(jié)點(diǎn)(前序遍歷) * Return 返回獲取的結(jié)點(diǎn)值 Status Value(Tree *T,int e){ if(T == null){ return error; } e = T->Value(T->leftChild); e = T->Value(T->rightChild); return e; } */ /** * Assign 給樹中某結(jié)點(diǎn)賦值為v(前序遍歷) * Return 返回賦值后的結(jié)點(diǎn)值 Status Assign(Tree *T,int e, TElementType v){ if(T == null){ return error; } e = T->Assign(T->leftChild); e = T->Assign(T->rightChilg); e = v; return e; } */三、二叉樹結(jié)構(gòu)基本實(shí)現(xiàn)
/** * PHP二叉樹算法 * Created on 2017-8-7 * Author entner * Email 1185087164@qq.com */ /* 假設(shè)我構(gòu)造一顆如下的二叉樹 A B C # D # # # # */ error_reporting(E_ALL ^ E_NOTICE); $data = array( 0=>"A", 1=>"B", 2=>"#", 3=>"D", 4=>"#", 5=>"#", 6=>"C", 7=>"#", 8=>"#", ); Class BTNode{ public $data; public $lChild; public $rChild; public function __construct($data = null){ $this->data = $data; } } Class BinaryTree{ public $root; public $btData; public function __construct($data = null){ $this->root = null; $this->btData = $data; //$this->preOrderCreateBT($this->root); } public function preOrderCreateBT(&$root = null){ $elem = array_shift($this->btData); //移除數(shù)組頭部,并作為結(jié)果返回 if($elem == null){ #判斷:當(dāng)數(shù)組為空時(shí) return ; }else if($elem == "#"){ #判斷:當(dāng)數(shù)組為無效單元時(shí),該節(jié)點(diǎn)是虛節(jié)點(diǎn),退出當(dāng)前遞歸,執(zhí)行下一個(gè)遞歸 $root = "#"; return $root; }else{ $root = new BTNode(); $root->data = $elem; $this->preOrderCreateBT($root->lChild); $this->preOrderCreateBT($root->rChild); } return $root; } /** * TODO:先序遍歷二叉樹 * @param $tree object 二叉樹 * @param $temp array 二叉樹輸出節(jié)點(diǎn)存儲(chǔ)數(shù)組 */ public function printBTPreOrder($tree,&$temp){ if($tree != null){ $temp[] = $tree->data; $this->printBTPreOrder($tree->lChild,$temp); $this->printBTPreOrder($tree->rChild,$temp); }else{ return ; } return $temp; } /** * TODO:中序遍歷二叉樹 * @param $tree object 二叉樹 * @param $temp array 二叉樹輸出節(jié)點(diǎn)存儲(chǔ)數(shù)組 */ public function printBTInOrder($tree,&$temp){ if($tree != null){ $this->printBTInOrder($tree->lChild,$temp); $temp[] = $tree->data; $this->printBTInOrder($tree->rChild,$temp); }else{ return; } return $temp; } /** * TODO:中序遍歷二叉樹 * @param $tree object 二叉樹 * @param $temp array 二叉樹輸出節(jié)點(diǎn)存儲(chǔ)數(shù)組 */ public function printBTPosOrder($tree,&$temp){ if($tree != null){ $this->printBTPosOrder($tree->lChild,$temp); $this->printBTPosOrder($tree->rChild,$temp); $temp[] = $tree->data; }else{ return; } return $temp; } /** * TODO:層序遍歷二叉樹(需要將書中節(jié)點(diǎn)放入隊(duì)中) * */ function PrintFromTopToBottom(&$root) { // write code here if($root == null){ return ; } $queue = array(); array_push($queue,$root); while(!is_null($node = array_shift($queue))){ echo $node->data . " "; if($node->left != null){ array_push($queue,$node->lChild); } if($node->left != null){ array_push($queue,$node->rChild); } } } } $object = new BinaryTree($data); $tree = $object->preOrderCreateBT($root); echo ""; print_r($tree);die;四、二叉排序樹/** *FindBitTree 二叉樹查找 *@param T BItTree 代指二叉樹及其元素結(jié)點(diǎn) *@param key int 樹中某結(jié)點(diǎn) *@param f point 指向該結(jié)點(diǎn)父結(jié)點(diǎn) *@param p point 指向該元素結(jié)點(diǎn)或空 *@param return bool true|false status SearchBST(BitTree T,int key,BitTree f = null,BitTree p){ if(!T){ p = f; return false; } if(key == T->data){ p = T;//其實(shí)就是根結(jié)點(diǎn) return true; }else if(key五、樹應(yīng)用實(shí)現(xiàn)-無限極分類(引用&遞歸)data){ SearchBST(T->lChild,int key,T,p); }else if(key >T->data){ SearchBST(T->rChild,int key,T,p); } } */ /** InsertBitTree 二叉樹插入 *【如果當(dāng)前樹中沒有key元素,則插入,插入的結(jié)點(diǎn)一定是葉子結(jié)點(diǎn)】 *@param T BItTree 代指二叉樹及其元素結(jié)點(diǎn) *@param key int 樹中某結(jié)點(diǎn) *@param return bool true|false status InsertBST(BitTree T,int key){ if(SearchBST(T,key,NULL,&p) == false){ s->data = key; s->lChild = s->rChild = NULL; if(!p){ T= s; }else if(key < p->data){ p->lChild = s; }else{ p->rChild = s; } return true; } return false; } */ $items = array( 1 => array("id" => 1, "pid" => 0, "name" => "江西省"), 2 => array("id" => 2, "pid" => 0, "name" => "黑龍江省"), 3 => array("id" => 3, "pid" => 1, "name" => "南昌市"), 4 => array("id" => 4, "pid" => 2, "name" => "哈爾濱市"), 5 => array("id" => 5, "pid" => 2, "name" => "雞西市"), 6 => array("id" => 6, "pid" => 4, "name" => "香坊區(qū)"), 7 => array("id" => 7, "pid" => 4, "name" => "南崗區(qū)"), 8 => array("id" => 8, "pid" => 6, "name" => "和興路"), 9 => array("id" => 9, "pid" => 7, "name" => "西大直街"), 10 => array("id" => 10, "pid" => 8, "name" => "東北林業(yè)大學(xué)"), 11 => array("id" => 11, "pid" => 9, "name" => "哈爾濱工業(yè)大學(xué)"), 12 => array("id" => 12, "pid" => 8, "name" => "哈爾濱師范大學(xué)"), 13 => array("id" => 13, "pid" => 1, "name" => "贛州市"), 14 => array("id" => 14, "pid" => 13, "name" => "贛縣"), 15 => array("id" => 15, "pid" => 13, "name" => "于都縣"), 16 => array("id" => 16, "pid" => 14, "name" => "茅店鎮(zhèn)"), 17 => array("id" => 17, "pid" => 14, "name" => "大田鄉(xiāng)"), 18 => array("id" => 18, "pid" => 16, "name" => "義源村"), 19 => array("id" => 19, "pid" => 16, "name" => "上壩村"), ); /** *TODO:通過引用方式實(shí)現(xiàn)無限極分類 * */ function tree_Classify1($items){ $tree=array(); $packData=array(); foreach ($items as $data) { $packData[$data["id"]] = $data; } foreach ($packData as $key =>$val){ if($val["pid"]==0){//代表跟節(jié)點(diǎn) $tree[]=& $packData[$key]; }else{ //找到其父類 $packData[$val["pid"]]["son"][]=& $packData[$key]; } } return $tree; } /** *TODO:通過遞歸方式實(shí)現(xiàn)無限極分類 * */ function tree_Classify2($items,$child="_child",$root = 0){ $tree=array(); foreach($items as $key=> $val){ if($val["pid"]==0){ //獲取當(dāng)前$pid所有子類 unset($items[$key]); if(! empty($items)){ $child=make_tree1($items,$child,$val["id"]); if(!empty($child)){ $val["_child"]=$child; } } $tree[]=$val; } } return $tree; } echo ""; print_r(make_tree1($items,$child="_child",$root=0)); ``
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/22923.html
摘要:回來更新一波,最近刷劍指,才又發(fā)現(xiàn)樹真是一個(gè)大頭,二叉樹的題目和變化運(yùn)用好多啊二叉樹算法引子很多人說二叉樹沒什么卵用,我覺得是他的工資和公司讓他跨不過這個(gè)坎還有很多人學(xué)了一些樹的知識(shí),發(fā)現(xiàn)也用不上,我想說的是,讀一本書體現(xiàn)不了這本書 回來更新一波,最近刷《劍指offer》,才又發(fā)現(xiàn)樹真是一個(gè)大頭,二叉樹的題目和變化運(yùn)用好多啊~ /** * PHP二叉樹算法 * Create...
摘要:二叉搜索樹是二叉樹的一種,其特征是左側(cè)子節(jié)點(diǎn)存儲(chǔ)比父節(jié)點(diǎn)小的值,右側(cè)子節(jié)點(diǎn)存儲(chǔ)比父節(jié)點(diǎn)大或等于父節(jié)點(diǎn)的值。實(shí)現(xiàn)和這個(gè)兩個(gè)方法其實(shí)挺簡(jiǎn)單的,最小的節(jié)點(diǎn)就在二叉搜索樹的最左反之,最大的就在最右。 本系列所有文章:第一篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之棧與隊(duì)列第二篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之鏈表第三篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之集合第四篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法之字典和散列表第五篇文章:學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)...
摘要:當(dāng)集合為空時(shí),稱該二叉樹為空二叉樹。也就是說,如果一個(gè)二叉樹的層數(shù)為,且結(jié)點(diǎn)總數(shù)是,則它就是滿二叉樹。完全二叉樹完全二叉樹是效率很高的數(shù)據(jù)結(jié)構(gòu),完全二叉樹是由滿二叉樹而引出來的。 ...
摘要:例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹并返回。操作給定的二叉樹,將其變換為源二叉樹的鏡像。劍指中還有一道類似的變種題目,就是下面的這道,之字形遍歷二叉樹。最后下面的兩道題目分別運(yùn)用了二叉樹先序中序遍歷算法。 開篇 以下內(nèi)容可能偏應(yīng)試但很好理解,所以大家一定要堅(jiān)持看下去,因?yàn)槲覀冏儚?qiáng)的過程注定孤獨(dú)的,堅(jiān)持下來就會(huì)看到明天的太陽。 回顧 showImg(https://user-...
摘要:二叉樹是數(shù)據(jù)結(jié)構(gòu)中很重要的結(jié)構(gòu)類型,學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)也是深入學(xué)習(xí)編程的必由之路,這里我們簡(jiǎn)單介紹下我對(duì)于二叉樹的理解,水平有限,如有錯(cuò)誤還請(qǐng)不吝賜教。 二叉樹是數(shù)據(jù)結(jié)構(gòu)中很重要的結(jié)構(gòu)類型,學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)也是深入學(xué)習(xí)編程的必由之路,這里我們簡(jiǎn)單介紹下我對(duì)于二叉樹的理解,水平有限,如有錯(cuò)誤還請(qǐng)不吝賜教。 首先照例定義一個(gè)二叉樹的節(jié)點(diǎn)類 class Node { private int ...
閱讀 3295·2023-04-26 02:40
閱讀 4648·2021-09-22 15:22
閱讀 1586·2021-09-22 10:02
閱讀 3481·2021-08-11 10:23
閱讀 1392·2019-08-30 15:55
閱讀 2493·2019-08-30 12:48
閱讀 586·2019-08-30 11:04
閱讀 702·2019-08-29 16:29