PHP 는 이 진 트 리 그래 픽 디 스 플레이 기능 에 대한 상세 한 설명 을 실현 합 니 다.[이 진 트 리,밸 런 스 트 리 및 레 드 블랙 트 리 포함]
선언:
최근 에 선생님 께 서 숙제 를 내 주 셨 습 니 다.균형 이 잡 힌 이 진 트 리 와 빨 간 검 은 나 무 를 이해 하고 실현 하 라 고 하 셨 습 니 다.원래 선생님 께 서 C\#로 쓰 셨 다 고 하 셨 는데 제 가 배 운 C\#는 선생님 께 거의 다 돌려 드 렸 습 니 다.어떻게 하 죠?그럼 지금 가장 익숙 한 언어 인 PHP 로 써 주세요!
한 가지 문제 가 있 습 니 다.책 에 서 는 나 무 를 설명 할 때 기본적으로 이미지 의 나무 그림 을 보 여 줍 니 다.그러나 우리 스스로 어떤 나 무 를 실현 하려 고 시도 할 때 디 버 깅,출력 할 때 문자 로 만 출력 할 수 있 습 니 다.이것 은 디 버 깅 등에 매우 큰 불편 을 가 져 왔 다.그리고 각종 바 이 두 후에 나 는 PHP 를 이용 하여 이 진 트 리 의 도형 을 나타 내 는 자원 이 거의 0 이라는 것 을 발견 했다!좋아,그럼 나 혼자 하나 실현 할 게!
효과 표시:
만약 에 제 가 이 단계 에서 코드 를 만 들 었 다 면 여러분 들 이 비교적 답답 할 것 입 니 다.그러면 제 가 바로 결 과 를 올 리 겠 습 니 다.그 다음 에 코드 를 보충 하고 여러분 들 의 읽 기 흥 미 를 자극 하 겠 습 니 다.
1.이 진 트 리 검색:
2.밸 런 스 이 진 트 리:
3.검 붉 은 나무:
상위 코드:
우리 그림 에 클래스 를 만 듭 시다.약간 고 급 스 러 워 보 입 니 다.
image.php 파일:
<?php
/**
* author:LSGOZJ
* description:
*/
class image
{
//
//
private $level_high = 100;
//
private $leaf_width = 50;
//
private $rad = 20;
//
private $leave = 20;
// ( )
private $tree;
//
private $level;
// ( , )
private $maxCount;
//
//
private $width;
//
private $height;
// (RGB)
private $bg = array(
220, 220, 220
);
// ( )
private $nodeColor = array(
255, 192, 203
);
//
private $image;
/**
* ,
* @param $tree
* @return null
*/
public function __construct($tree)
{
$this->tree = $tree;
$this->level = $this->getLevel();
$this->maxCount = $this->GetMaxCount($this->level);
$this->width = ($this->rad * 2 * $this->maxCount) + $this->maxCount * $this->leaf_width;
$this->height = $this->level * ($this->rad * 2) + $this->level_high * ($this->level - 1) + $this->leave;
//1.
$this->image = imagecreatetruecolor($this->width, $this->height); // ,
//
$bgcolor = imagecolorallocate($this->image, $this->bg[0], $this->bg[1], $this->bg[2]);
imagefill($this->image, 0, 0, $bgcolor);
}
/**
*
* @param $level
* @return
*/
function GetMaxCount($level)
{
return pow(2, $level - 1);
}
/**
*
* @param null
* @return
*/
function getLevel()
{
return $this->tree->Depth();
}
/**
*
* @param null
* @return null
*/
public function show()
{
$this->draw($this->tree->root, 1, 0, 0);
header("Content-type:image/png");
imagepng($this->image);
imagedestroy($this->image);
}
/**
* ( )
* @param $root, ( ) $i, $p_x, x $p_y, y
* @return null
*/
private function draw($root, $i, $p_x, $p_y)
{
if ($i <= $this->level) {
// y
$root_y = $i * $this->rad + ($i - 1) * $this->level_high;
// x
if (!is_null($parent = $root->parent)) {
if ($root == $parent->left) {
$root_x = $p_x - $this->width / (pow(2, $i));
} else {
$root_x = $p_x + $this->width / (pow(2, $i));
}
} else {
//
$root_x = (1 / 2) * $this->width;
$root_y += $this->leave;
}
// ( ( 、 、 ) )
$method = 'draw' . get_class($this->tree) . 'Node';
$this->$method($root_x, $root_y, $root);
// ( )
$black = imagecolorallocate($this->image, 0, 0, 0);
if (!is_null($parent = $root->parent)) {
imageline($this->image, $p_x, $p_y, $root_x, $root_y, $black);
}
//
if (!is_null($root->left)) {
$this->draw($root->left, $i + 1, $root_x, $root_y);
}
//
if (!is_null($root->right)) {
$this->draw($root->right, $i + 1, $root_x, $root_y);
}
}
}
/**
*
* @param $x, x $y, y $node,
* @return null
*/
private function drawBstNode($x, $y, $node)
{
//
$black = imagecolorallocate($this->image, 0, 0, 0);
$nodeColor = imagecolorallocate($this->image, $this->nodeColor[0], $this->nodeColor[1], $this->nodeColor[2]);
//
imageellipse($this->image, $x, $y, $this->rad * 2, $this->rad * 2, $black);
//
imagefill($this->image, $x, $y, $nodeColor);
//
imagestring($this->image, 4, $x, $y, $node->key, $black);
}
/**
*
* @param $x, x $y, y $node,
* @return null
*/
private function drawAvlNode($x, $y, $node)
{
$black = imagecolorallocate($this->image, 0, 0, 0);
$nodeColor = imagecolorallocate($this->image, $this->nodeColor[0], $this->nodeColor[1], $this->nodeColor[2]);
imageellipse($this->image, $x, $y, $this->rad * 2, $this->rad * 2, $black);
imagefill($this->image, $x, $y, $nodeColor);
imagestring($this->image, 4, $x, $y, $node->key . '(' . $node->bf . ')', $black);
}
/**
*
* @param $x, x $y, y $node,
* @return null
*/
private function drawRbtNode($x, $y, $node)
{
$black = imagecolorallocate($this->image, 0, 0, 0);
$gray = imagecolorallocate($this->image, 180, 180, 180);
$pink = imagecolorallocate($this->image, 255, 192, 203);
imageellipse($this->image, $x, $y, $this->rad * 2, $this->rad * 2, $black);
if ($node->IsRed == TRUE) {
imagefill($this->image, $x, $y, $pink);
} else {
imagefill($this->image, $x, $y, $gray);
}
imagestring($this->image, 4, $x, $y, $node->key, $black);
}
}
자,이제 클 라 이언 트 에서 어떻게 호출 하 는 지 봅 시다.client.php
class Client
{
public static function Main()
{
try {
//
function autoload($class)
{
include strtolower($class) . '.php';
}
spl_autoload_register('autoload');
$arr = array(62, 88, 58, 47, 35, 73, 51, 99, 37, 93);
// $tree = new Bst(); //
$tree = new Avl(); //
// $tree = new Rbt(); //
$tree->init($arr); //
// $tree->Delete(62);
// $tree->Insert(100);
// $tree->MidOrder(); // ( , )
$image = new image($tree);
$image->show(); //
} catch (Exception $e) {
echo $e->getMessage();
}
}
}
Client::Main();
여기에 사용 되 는 세 나무의 종 류 는 다음 과 같다.두 갈래 검색 트 리 bst.php:
<?php
/**
* author:zhongjin
* description:
*/
//
class Node
{
public $key;
public $parent;
public $left;
public $right;
public function __construct($key)
{
$this->key = $key;
$this->parent = NULL;
$this->left = NULL;
$this->right = NULL;
}
}
//
class Bst
{
public $root;
/**
*
* @param $arr
* @return null
*/
public function init($arr)
{
$this->root = new Node($arr[0]);
for ($i = 1; $i < count($arr); $i++) {
$this->Insert($arr[$i]);
}
}
/**
* ( )
* @param $root ( )
* @return null
*/
private function mid_order($root)
{
if ($root != NULL) {
$this->mid_order($root->left);
echo $root->key . " ";
$this->mid_order($root->right);
}
}
/**
* ( )
* @param null
* @return null
*/
public function MidOrder()
{
$this->mid_order($this->root);
}
/**
* $key
* @param $key
* @return $key
*/
function search($key)
{
$current = $this->root;
while ($current != NULL) {
if ($current->key == $key) {
return $current;
} elseif ($current->key > $key) {
$current = $current->left;
} else {
$current = $current->right;
}
}
return $current;
}
/**
*
* @param $root
* @return
*/
function search_min($root)
{
$current = $root;
while ($current->left != NULL) {
$current = $current->left;
}
return $current;
}
/**
*
* @param $root
* @return
*/
function search_max($root)
{
$current = $root;
while ($current->right != NULL) {
$current = $current->right;
}
return $current;
}
/**
* $key
* @param $x
* @return
*/
function predecessor($x)
{
// ,
if ($x->left != NULL) {
return $this->search_max($x->left);
}
// ,
$p = $x->parent;
// x p , p x , p x
while ($p != NULL && $x == $p->left) {
$x = $p;
$p = $p->parent;
}
return $p;
}
/**
* $key
* @param $x
* @return
*/
function successor($x)
{
if ($x->right != NULL) {
return $this->search_min($x->right);
}
$p = $x->parent;
while ($p != NULL && $x == $p->right) {
$x = $p;
$p = $p->parent;
}
return $p;
}
/**
* $key
* @param $key
* @return null
*/
function Insert($key)
{
if (!is_null($this->search($key))) {
throw new Exception(' ' . $key . ' , !');
}
$root = $this->root;
$inode = new Node($key);
$current = $root;
$prenode = NULL;
// $inode
while ($current != NULL) {
$prenode = $current;
if ($current->key > $inode->key) {
$current = $current->left;
} else {
$current = $current->right;
}
}
$inode->parent = $prenode;
// $prenode == NULL,
if ($prenode == NULL) {
$this->root = $inode;
} else {
if ($inode->key < $prenode->key) {
$prenode->left = $inode;
} else {
$prenode->right = $inode;
}
}
//return $root;
}
/**
* $key
* @param $key
* @return null
*/
function Delete($key)
{
if (is_null($this->search($key))) {
throw new Exception(' ' . $key . " , !");
}
$root = $this->root;
$dnode = $this->search($key);
if ($dnode->left == NULL || $dnode->right == NULL) { # , c = dnode
$c = $dnode;
} else { # ,c dnode ,
$c = $this->successor($dnode);
}
// , c
if ($c->left != NULL) {
$s = $c->left;
} else {
$s = $c->right;
}
if ($s != NULL) { # c c , c 1 , c , c dnode
$s->parent = $c->parent;
}
if ($c->parent == NULL) { # c , c=dnode , , dnode , , c dnode ,c , if
$this->root = $s;
} else if ($c == $c->parent->left) { # c , c c
$c->parent->left = $s;
} else {
$c->parent->right = $s;
}
# c!=dnode, c dnode , c dnode key
if ($c != $dnode) {
$dnode->key = $c->key;
}
#
// return $root;
}
/**
* ( )
* @param $root
* @return
*/
private function getdepth($root)
{
if ($root == NULL) {
return 0;
}
$dl = $this->getdepth($root->left);
$dr = $this->getdepth($root->right);
return ($dl > $dr ? $dl : $dr) + 1;
}
/**
* ( )
* @param null
* @return null
*/
public function Depth()
{
return $this->getdepth($this->root);
}
}
?>
균형 트 리 avl.php:
<?php
/**
* author:zhongjin
* description:
*/
//
class Node
{
public $key;
public $parent;
public $left;
public $right;
public $bf; //
public function __construct($key)
{
$this->key = $key;
$this->parent = NULL;
$this->left = NULL;
$this->right = NULL;
$this->bf = 0;
}
}
//
class Avl
{
public $root;
const LH = +1; //
const EH = 0; //
const RH = -1; //
/**
*
* @param $arr
* @return null
*/
public function init($arr)
{
$this->root = new Node($arr[0]);
for ($i = 1; $i < count($arr); $i++) {
$this->Insert($arr[$i]);
}
}
/**
* ( )
* @param $root ( )
* @return null
*/
private function mid_order($root)
{
if ($root != NULL) {
$this->mid_order($root->left);
echo $root->key . "-" . $root->bf . " ";
$this->mid_order($root->right);
}
}
/**
* ( )
* @param null
* @return null
*/
public function MidOrder()
{
$this->mid_order($this->root);
}
/**
* $root
* @param $root( )
* @return null
*/
private function R_Rotate($root)
{
$L = $root->left;
if (!is_NULL($root->parent)) {
$P = $root->parent;
if ($root == $P->left) {
$P->left = $L;
} else {
$P->right = $L;
}
$L->parent = $P;
} else {
$L->parent = NULL;
}
$root->parent = $L;
$root->left = $L->right;
$L->right = $root;
// !
if ($L->parent == NULL) {
$this->root = $L;
}
}
/**
* $root
* @param $root( )
* @return null
*/
private function L_Rotate($root)
{
$R = $root->right;
if (!is_NULL($root->parent)) {
$P = $root->parent;
if ($root == $P->left) {
$P->left = $R;
} else {
$P->right = $R;
}
$R->parent = $P;
} else {
$R->parent = NULL;
}
$root->parent = $R;
$root->right = $R->left;
$R->left = $root;
// !
if ($R->parent == NULL) {
$this->root = $R;
}
}
/**
* $root
* @param $root( )
* @return null
*/
public function LeftBalance($root)
{
$L = $root->left;
$L_bf = $L->bf;
switch ($L_bf) {
// root ,
case self::LH: // root ,
$root->bf = $L->bf = self::EH;
$this->R_Rotate($root);
break;
case self::RH: // root ,
$L_r = $L->right; //root
$L_r_bf = $L_r->bf;
// root
switch ($L_r_bf) {
case self::LH:
$root->bf = self::RH;
$L->bf = self::EH;
break;
case self::EH:
$root->bf = $L->bf = self::EH;
break;
case self::RH:
$root->bf = self::EH;
$L->bf = self::LH;
break;
}
$L_r->bf = self::EH;
// root
$this->L_Rotate($L);
// root
$this->R_Rotate($root);
}
}
/**
* $root
* @param $root( )
* @return null
*/
public function RightBalance($root)
{
$R = $root->right;
$R_bf = $R->bf;
switch ($R_bf) {
// root ,
case self::RH: // root ,
$root->bf = $R->bf = self::EH;
$this->L_Rotate($root);
break;
case self::LH: // root ,
$R_l = $R->left; //root
$R_l_bf = $R_l->bf;
// root
switch ($R_l_bf) {
case self::RH:
$root->bf = self::LH;
$R->bf = self::EH;
break;
case self::EH:
$root->bf = $R->bf = self::EH;
break;
case self::LH:
$root->bf = self::EH;
$R->bf = self::RH;
break;
}
$R_l->bf = self::EH;
// root
$this->R_Rotate($R);
// root
$this->L_Rotate($root);
}
}
/**
* $key
* @param $key
* @return $key
*/
public function search($key)
{
$current = $this->root;
while ($current != NULL) {
if ($current->key == $key) {
return $current;
} elseif ($current->key > $key) {
$current = $current->left;
} else {
$current = $current->right;
}
}
return $current;
}
/**
*
* @param $root
* @return
*/
function search_min($root)
{
$current = $root;
while ($current->left != NULL) {
$current = $current->left;
}
return $current;
}
/**
*
* @param $root
* @return
*/
function search_max($root)
{
$current = $root;
while ($current->right != NULL) {
$current = $current->right;
}
return $current;
}
/**
* $key
* @param $x
* @return
*/
private function predecessor($x)
{
// ,
if ($x->left != NULL) {
return $this->search_max($x->left);
}
// ,
$p = $x->parent;
// x p , p x , p x
while ($p != NULL && $x == $p->left) {
$x = $p;
$p = $p->parent;
}
return $p;
}
/**
* $key
* @param $x
* @return
*/
private function successor($x)
{
if ($x->left != NULL) {
return $this->search_min($x->right);
}
$p = $x->parent;
while ($p != NULL && $x == $p->right) {
$x = $p;
$p = $p->parent;
}
return $p;
}
/**
* ( ) , ,
* @param $root $key
* @return null
*/
private function insert_node(&$root, $key)
{
// ,
if (is_null($root)) {
$root = new Node($key);
//
return TRUE;
} else {
// $key
if ($key == $root->key) {
//
return FALSE;
} // root
elseif ($key < $root->key) {
//
if (!($this->insert_node($root->left, $key))) {
//
return FALSE;
}
// ,
if (is_null($root->left->parent)) {
$root->left->parent = $root;
}
switch ($root->bf) {
// ,
case self::EH:
$root->bf = self::LH;
//
return TRUE;
break;
// ,
case self::LH:
$this->LeftBalance($root);
// ,
return FALSE;
break;
// ,
case self::RH:
$root->bf = self::EH;
//
return FALSE;
break;
}
} // root
else {
//
if (!$this->insert_node($root->right, $key)) {
//
return FALSE;
}
// ,
if (is_null($root->right->parent)) {
$root->right->parent = $root;
}
switch ($root->bf) {
// ,
case self::EH:
$root->bf = self::RH;
//
return TRUE;
break;
// ,
case self::LH:
$root->bf = self::EH;
return FALSE;
break;
// ,
case self::RH:
$this->RightBalance($root);
//
return FALSE;
break;
}
}
}
}
/**
* ( ) $key
* @param $key
* @return null
*/
public function Insert($key)
{
$this->insert_node($this->root, $key);
}
/**
* ( )
* @param $key
* @return
*/
private function get_del_node($key)
{
$dnode = $this->search($key);
if ($dnode == NULL) {
throw new Exception(" !");
return;
}
if ($dnode->left == NULL || $dnode->right == NULL) { # , c = dnode
$c = $dnode;
} else { # ,c dnode ,
$c = $this->successor($dnode);
}
$dnode->key = $c->key;
return $c;
}
/**
* ( ) ,
* @param $node
* @return null
*/
private function del_node($node)
{
if ($node == $this->root) {
$this->root = NULL;
return;
}
$current = $node;
// node , ,
$P = $current->parent;
// ,
$lower = TRUE;
while ($lower == TRUE && !is_null($P)) {
//
if ($current == $P->left) {
if($current == $node){
if (!is_null($current->left)) {
$P->left = $current->left;
} else {
$P->left = $current->left;
}
}
$P_bf = $P->bf;
switch ($P_bf) {
case self::LH:
$P->bf = self::EH;
$lower = TRUE;
$current = $P;
$P = $current->parent;
break;
case self::EH:
$P->bf = self::RH;
$lower = FALSE;
break;
case self::RH:
$this->RightBalance($P);
$lower = TRUE;
$current = $P->parent;
$P = $current->parent;
break;
}
} //
else {
if($current == $node){
if (!is_null($current->left)) {
$P->right = $current->left;
} else {
$P->right = $current->left;
}
}
$P_bf = $P->bf;
switch ($P_bf) {
case self::LH:
$this->LeftBalance($P);
$lower = TRUE;
$current = $P->parent;
$P = $current->parent;
break;
case self::EH:
$P->bf = self::LH;
$lower = FALSE;
break;
case self::RH:
$P->bf = self::LH;
$lower = TRUE;
$current = $P;
$P = $current->parent;
break;
}
}
}
}
/**
* ( )
* @param $key key
* @return null
*/
public function Delete($key)
{
$del_node = $this->get_del_node($key);
$this->del_node($del_node);
}
/**
* ( )
* @param $root
* @return
*/
private function getdepth($root)
{
if ($root == NULL) {
return 0;
}
$dl = $this->getdepth($root->left);
$dr = $this->getdepth($root->right);
return ($dl > $dr ? $dl : $dr) + 1;
}
/**
* ( )
* @param null
* @return null
*/
public function Depth()
{
return $this->getdepth($this->root);
}
}
?>
붉 은 검 은 나무 rbt.php:
<?php
/**
* author:zhongjin
* description:
*/
//
class Node
{
public $key;
public $parent;
public $left;
public $right;
public $IsRed; //
public function __construct($key, $IsRed = TRUE)
{
$this->key = $key;
$this->parent = NULL;
$this->left = NULL;
$this->right = NULL;
//
$this->IsRed = $IsRed;
}
}
//
class Rbt
{
public $root;
/**
*
* @param $arr
* @return null
*/
public function init($arr)
{
//
$this->root = new Node($arr[0], FALSE);
for ($i = 1; $i < count($arr); $i++) {
$this->Insert($arr[$i]);
}
}
/**
* ( )
* @param $root ( )
* @return null
*/
private function mid_order($root)
{
if ($root != NULL) {
$this->mid_order($root->left);
echo $root->key . "-" . ($root->IsRed ? 'r' : 'b') . ' ';
$this->mid_order($root->right);
}
}
/**
* ( )
* @param null
* @return null
*/
public function MidOrder()
{
$this->mid_order($this->root);
}
/**
* $key
* @param $key
* @return $key
*/
function search($key)
{
$current = $this->root;
while ($current != NULL) {
if ($current->key == $key) {
return $current;
} elseif ($current->key > $key) {
$current = $current->left;
} else {
$current = $current->right;
}
}
//
return $current;
}
/**
* $root
* @param $root( )
* @return null
*/
private function R_Rotate($root)
{
$L = $root->left;
if (!is_null($root->parent)) {
$P = $root->parent;
if($root == $P->left){
$P->left = $L;
}else{
$P->right = $L;
}
$L->parent = $P;
} else {
$L->parent = NULL;
}
$root->parent = $L;
$root->left = $L->right;
$L->right = $root;
// !
if ($L->parent == NULL) {
$this->root = $L;
}
}
/**
* $root
* @param $root( )
* @return null
*/
private function L_Rotate($root)
{
$R = $root->right;
if (!is_null($root->parent)) {
$P = $root->parent;
if($root == $P->right){
$P->right = $R;
}else{
$P->left = $R;
}
$R->parent = $P;
} else {
$R->parent = NULL;
}
$root->parent = $R;
$root->right = $R->left;
$R->left = $root;
// !
if ($R->parent == NULL) {
$this->root = $R;
}
}
/**
*
* @param $root
* @return
*/
function search_min($root)
{
$current = $root;
while ($current->left != NULL) {
$current = $current->left;
}
return $current;
}
/**
*
* @param $root
* @return
*/
function search_max($root)
{
$current = $root;
while ($current->right != NULL) {
$current = $current->right;
}
return $current;
}
/**
* $key
* @param $x
* @return
*/
function predecessor($x)
{
// ,
if ($x->left != NULL) {
return $this->search_max($x->left);
}
// ,
$p = $x->parent;
// x p , p x , p x
while ($p != NULL && $x == $p->left) {
$x = $p;
$p = $p->parent;
}
return $p;
}
/**
* $key
* @param $x
* @return
*/
function successor($x)
{
if ($x->left != NULL) {
return $this->search_min($x->right);
}
$p = $x->parent;
while ($p != NULL && $x == $p->right) {
$x = $p;
$p = $p->parent;
}
return $p;
}
/**
* $key
* @param $key
* @return null
*/
public function Insert($key)
{
if (!is_null($this->search($key))) {
throw new Exception(' ' . $key . ' , !');
}
$root = $this->root;
$inode = new Node($key);
$current = $root;
$prenode = NULL;
// $inode
while ($current != NULL) {
$prenode = $current;
if ($current->key > $inode->key) {
$current = $current->left;
} else {
$current = $current->right;
}
}
$inode->parent = $prenode;
// $prenode == NULL,
if ($prenode == NULL) {
$this->root = $inode;
} else {
if ($inode->key < $prenode->key) {
$prenode->left = $inode;
} else {
$prenode->right = $inode;
}
}
//
$this->InsertFixUp($inode);
}
/**
*
* @param $inode
* @return null
*/
private function InsertFixUp($inode)
{
// : ,
while (($parent = $inode->parent) != NULL && $parent->IsRed == TRUE) {
// :
$gparent = $parent->parent;
// , else
if ($parent == $gparent->left) {
//
$uncle = $gparent->right;
//case1:
if ($uncle != NULL && $uncle->IsRed == TRUE) {
// ,
$parent->IsRed = FALSE;
$uncle->IsRed = FALSE;
$gparent->IsRed = TRUE;
// ( , )
$inode = $gparent;
// while ,
continue; // , ( case2)
}
//case2: ,
if ($inode == $parent->right) {
//
$this->L_Rotate($parent);
// , ,
// ,
$temp = $parent;
$parent = $inode;
$inode = $temp;
}
//case3: ,
$parent->IsRed = FALSE;
$gparent->IsRed = TRUE;
$this->R_Rotate($gparent);
} // ,
else {
//
$uncle = $gparent->left;
//case1:
if ($uncle != NULL && $uncle->IsRed == TRUE) {
// ,
$parent->IsRed = FALSE;
$uncle->IsRed = FALSE;
$gparent->IsRed = TRUE;
// ( , )
$inode = $gparent;
// while ,
continue; // , ( case2)
}
//case2: ,
if ($inode == $parent->left) {
//
$this->R_Rotate($parent);
// , ,
// ,
$temp = $parent;
$parent = $inode;
$inode = $temp;
}
//case3: ,
$parent->IsRed = FALSE;
$gparent->IsRed = TRUE;
$this->L_Rotate($gparent);
}
}
// : ( ),
if ($inode == $this->root) {
$this->root->IsRed = FALSE;
return;
}
// : ,
if ($inode->parent != NULL && $inode->parent->IsRed == FALSE) {
return;
}
}
/**
* ( )
* @param $key key
* @return null
*/
function Delete($key)
{
if (is_null($this->search($key))) {
throw new Exception(' ' . $key . " , !");
}
$dnode = $this->search($key);
if ($dnode->left == NULL || $dnode->right == NULL) { # , c = dnode
$c = $dnode;
} else { # ,c dnode ,
$c = $this->successor($dnode);
}
//
$parent = $c->parent;
// , c
if ($c->left != NULL) { // ,
$s = $c->left;
} else {
$s = $c->right;
}
if ($s != NULL) { # c c , c 1 , c , c dnode
$s->parent = $c->parent;
}
if ($c->parent == NULL) { # c , c=dnode , , dnode , , c dnode ,c , if
$this->root = $s;
} else if ($c == $c->parent->left) { # c , c c
$c->parent->left = $s;
} else {
$c->parent->right = $s;
}
$dnode->key = $c->key;
$node = $s;
//c , ,
if ($c->IsRed == FALSE) {
$this->DeleteFixUp($node,$parent);
}
}
/**
*
* @param $key
* @return null
*/
private function DeleteFixUp($node,$parent)
{
// ,
if ($node != NULL && $node->IsRed == TRUE) {
$node->IsRed = FALSE;
return;
}
// ,
while (($node == NULL || $node->IsRed == FALSE) && ($node != $this->root)) {
//node , else
if ($node == $parent->left) {
$brother = $parent->right;
//case1: ( )
// , , ( , )
if ($brother->IsRed == TRUE) {
$brother->IsRed = FALSE;
$parent->IsRed = TRUE;
$this->L_Rotate($parent);
//
$brother = $parent->right; // ,$parent->right
}
//
//case2: ,
// , , 。
if (($brother->left == NULL || $brother->left->IsRed == FALSE) && ($brother->right == NULL || $brother->right->IsRed == FALSE)) {
$brother->IsRed = TRUE;
$node = $parent;
$parent = $node->parent;
} else {
//case3: , ,
// , , ( , , )
if ($brother->right == NULL || $brother->right->IsRed == FALSE) {
$brother->IsRed = TRUE;
$brother->left->IsRed = FALSE;
$this->R_Rotate($brother);
//
$brother = $parent->right;
}
//case4: , ,
// , , ,
$brother->IsRed = $parent->IsRed;
$parent->IsRed = FALSE;
$brother->right->IsRed = FALSE;
$this->L_Rotate($parent);
// , ,
$node = $this->root;
break;
}
} //node
else {
$brother = $parent->left;
//case1: ( )
// , , ( , )
if ($brother->IsRed == TRUE) {
$brother->IsRed = FALSE;
$parent->IsRed = TRUE;
$this->R_Rotate($parent);
//
$brother = $parent->left; // ,$parent->left
}
//
//case2: ,
// , , 。
if (($brother->left == NULL || $brother->left->IsRed == FALSE) && ($brother->right == NULL || $brother->right->IsRed == FALSE)) {
$brother->IsRed = TRUE;
$node = $parent;
$parent = $node->parent;
} else {
//case3: , ,
// , , ( , , )
if ($brother->left == NULL || $brother->left->IsRed == FALSE) {
$brother->IsRed = TRUE;
$brother->right = FALSE;
$this->L_Rotate($brother);
//
$brother = $parent->left;
}
//case4: , ,
// , , ,
$brother->IsRed = $parent->IsRed;
$parent->IsRed = FALSE;
$brother->left->IsRed = FALSE;
$this->R_Rotate($parent);
$node = $this->root;
break;
}
}
}
if ($node != NULL) {
$this->root->IsRed = FALSE;
}
}
/**
* ( )
* @param $root
* @return
*/
private function getdepth($root)
{
if ($root == NULL) {
return 0;
}
$dl = $this->getdepth($root->left);
$dr = $this->getdepth($root->right);
return ($dl > $dr ? $dl : $dr) + 1;
}
/**
* ( )
* @param null
* @return null
*/
public function Depth()
{
return $this->getdepth($this->root);
}
}
?>
더 많은 PHP 관련 내용 에 관심 이 있 는 독자 들 은 본 사이트 의 주 제 를 볼 수 있다.본 논문 에서 말 한 것 이 여러분 의 PHP 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
laravel에 yo에서 angularJs&coffeescript를 사용할 수 있도록 한다.먼저 yo 명령을 사용할 수 있어야하므로 아래에서 설치 global에 설치한 곳에서 laravel의 프로젝트 루트로 이동. 클라이언트 코드를 관리하는 디렉토리를 만들고 이동합니다. 클라이언트 환경 만들기 이것으로 히...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.