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