樹的概念:
樹是一種非線性的資料結構,一般由根結點【樹根】和N棵子樹構成,同時M棵子樹構成的稱為森林。
下面給個圖
其中A第一層,B,C第二層,DEFG第三層,H第四層
二叉樹的概念:
都是樹,只不過呢每個結點子樹最多為2棵子樹,左子樹和右子樹是有順序的,二叉樹分類有左斜樹,右斜樹,滿二叉樹,完全二叉樹等
斜樹
滿二叉樹
完全二叉樹
遍歷演算法:
前序【有的叫先序?】,中序,後序,層序遍歷
遍歷演算法的目的:只是把非線性結點的二叉樹折騰成線性結構好迴圈,就這樣,不要覺得很歷害!^_^
線性結構是啥,可以看本人前面寫過的棧,佇列這些玩意哦
下面給個小例子吧
$bitree = [
'a'=>[
'b'=>[
'd',
'e'
],
'c'=>[
'f',
'g'
]
]
];
就是長這樣的二叉樹
當然了,要是人家寫的二叉樹資料結構一般都是這樣的
typedef struct tree{
int data;
struct tree *ltree;
struct tree *rtree;
}tree,*Bitree;
這是c的二叉鏈資料結構,有左,右之分,我懶的搞了,用個陣列代替一下嘍,
下面我們寫個後序遍歷演算法【其實很簡單^_^】
後序遍歷的話就是輸出:DEBFGCA
function preTraverse($a)
{
foreach ($a as $k=>$item){
if (is_array($item)){
preTraverse($item);
echo $k.PHP_EOL;
}else{
echo $item.PHP_EOL;
}
}
}
輸出結點圖:
吶,簡單吧,就一個遞迴就實現了,下面我們弄個大森林【也是樹】
$a = [
'a'=>[
'1'=>[
'4'=>[
'13'=>[
'40'=>[
'121'=>[
'124'=>[
'127'=>[
'130'=>[
'133'=>[
'136'=>[
'139'=>[
'142'=>[
'145'=>[
'148'=>[
'151'=>[
'154'=>[
'157'=>[
'160'=>[
'163'=>[
'166'=>[
'169'=>[
'172'=>[
'175'=>[
'178'=>[
'181'=>[
'184'=>[
'187'=>[
'190'=>[
'193'=>[
'196'=>[
'199',
'200'
],
'197',
'198'
],
'194',
'195'
],
'191',
'192'
],
'188',
'189'
],
'185',
'186'
],
'182',
'183'
],
'179',
'180'
],
'176',
'177'
],
'173',
'174',
],
'170',
'171'
],
'167',
'168'
],
'164',
'165'
],
'161',
'162'
],
'158',
'159'
],
'155',
'156'
],
'152',
'153'
],
'149',
'150'
],
'146',
'147'
],
'143',
'144'
],
'140',
'141'
],
'137',
'138'
],
'134',
'135'
],
'131',
'132'
],
'128',
'129'
],
'125',
'126'
],
'122',
'123'
],
'41',
'42'
],
'14'=>[
'43',
'44',
'45'
],
'15'=>[
'46',
'47',
'48'
]
],
'5'=>[
'16'=>[
'49',
'50',
'51'
],
'17'=>[
'52',
'53',
'54'
],
'18'=>[
'55',
'56',
'57'
]
],
'6'=>[
'19'=>[
'58',
'59',
'60'
],
'20'=>[
'61',
'62',
'63'
],
'21'=>[
'64',
'65',
'66'
]
]
],
'2'=>[
'7'=>[
'22'=>[
'67',
'68',
'69'
],
'23'=>[
'70',
'71',
'72'
],
'24'=>[
'73',
'74',
'75'
]
],
'8'=>[
'25'=>[
'76',
'77',
'78'
],
'26'=>[
'79',
'80',
'81'
],
'27'=>[
'82',
'83',
'84'
]
],
'9'=>[
'28'=>[
'85',
'86',
'87',
],
'29'=>[
'88',
'89',
'90'
],
'30'=>[
'91',
'92',
'93'
]
]
],
'3'=>[
'10'=>[
'31'=>[
'94',
'95',
'96'
],
'32'=>[
'97',
'98',
'99'
],
'33'=>[
'100',
'101',
'102'
]
],
'11'=>[
'34'=>[
'103',
'104',
'105'
],
'35'=>[
'106',
'107',
'108'
],
'36'=>[
'109',
'110',
'111'
]
],
'12'=>[
'37'=>[
'112',
'113',
'114'
],
'38'=>[
'115',
'116',
'117',
],
'39'=>[
'118',
'119',
'120'
]
]
],
'test'=>[
'a',
'b',
'c',
'd',
'e'=>[
'f'=>'g',
'h'=>[
'i'=>[
'j'=>[
'k'=>[
'l'=>[
'm'=>[
'n'=>[
'o'=>[
'p'=>[
'q'=>[
'r'=>[
's'=>[
't'=>[
'u'=>[
'v'=>[
'w'=>[
'x'=>[
'y'=>[
'z'=>[
'aa'=>[
'bb'=>[
'cc'=>[
'dd'=>[
'ee'=>[
'ff'=>[
'gg'=>[
'hh'=>[
'ii'=>[
'jj'=>[
'kk'=>[
'll'=>[
'mm'=>[
'nn'=>[
'oo'=>[
'pp'=>[
'qq'=>[
'rr'=>[
'ss'=>[
'tt'=>[
'uu'=>[
'vv'=>[
'ww'=>[
'xx'=>[
'yy'=>[
'zz'
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
],
'haha'=>[
'h'
]
],
];
數字從1到200,字母從a到z再從aa-zz,演算法都一樣
輸出結果我就不截圖了,自己執行一下就知道了。
一般二叉樹我們會用到,比如家譜圖的生成。
下面是正常的二叉樹前序,中序,後序遍歷演算法
<?php
/**
* Created by PhpStorm.
* User: 1655664358@qq.com
* Date: 2019/7/5
* Time: 9:25
*/
class Tree
{
public $data;
public $lTree;
public $rTree;
}
function initTree()
{
$tree = new Tree();
$tree->data = 'A';
$nodeB = clone $tree;
$nodeB->data = 'B';
$nodeD = clone $tree;
$nodeD->data = 'D';
$nodeD->lTree = NULL;
$nodeD->rTree = NULL;
$nodeE = clone $tree;
$nodeE->data = 'E';
$nodeE->lTree = NULL;
$nodeE->rTree = NULL;
$nodeB->lTree = $nodeD;
$nodeB->rTree = $nodeE;
$nodeC = clone $tree;
$nodeC->data = 'C';
$nodeF = clone $tree;
$nodeF->data = 'F';
$nodeF->lTree = NULL;
$nodeF->rTree = NULL;
$nodeG = clone $tree;
$nodeG->data = 'G';
$nodeG->lTree = NULL;
$nodeG->rTree = NULL;
$nodeC->lTree = $nodeF;
$nodeC->rTree = $nodeG;
$tree->lTree = $nodeB;
$tree->rTree = $nodeC;
return $tree;
}
function displayTreeNode($tree)
{
if (!is_null($tree)){
echo $tree->data;
}
}
function preTraverse($tree){
if (!is_null($tree)){
displayTreeNode($tree);
preTraverse($tree->lTree);
preTraverse($tree->rTree);
}
}
function inTraverse($tree){
if (!is_null($tree)){
inTraverse($tree->lTree);
displayTreeNode($tree);
inTraverse($tree->rTree);
}
}
function lastTraverse($tree){
if (!is_null($tree)){
lastTraverse($tree->lTree);
lastTraverse($tree->rTree);
displayTreeNode($tree);
}
}
/**
* A
* B C
* D E F G
*/
//前序遍歷
$tree = initTree();
preTraverse($tree);
echo PHP_EOL;
//中序遍歷
inTraverse($tree);
echo PHP_EOL;
//後序遍歷
lastTraverse($tree);