<?php#将二叉查找树转换为双向链表,要求不能创建新节点,只能调节节点指针#解题思路是从树的底层开始,调整每个节点的左右子树,将左子树的最大节点与根节点相连,将又子树的最小节点与根节点相连#我们把节点的left当做链表的pre指针,right当做链表的next指针#直到所有子树以及根节点转换完成#树节点class Node {public $data = null;public $parent = null;public $left = null;public $right = null;}#查找树最小节点function search_min($root) {$cnode = $root;while ($cnode->left != null) {$cnode = $cnode->left;}return $cnode;}#查找树的最打节点function search_max($root) {$cnode = $root;while ($cnode->right != null) {$cnode = $cnode->right;}return $cnode;}#查找某个节点中序遍历的前趋function predecessor($node) {#如果该节点存在左子树,则查找其左子树的最大值if ($node->left != null) {return search_max($left);}#否则查找其父节点,直到当前节点是其父节点的右孩子$p = $node->parent;while ($p != null && $node == $p->left) {$node = $p;$p = $p->parent;}return $p;}#查找某个节点中序遍历的后继function successor($node) {#如果该节点存在右子树,则查找其右子树的最小值if ($node->right != null) {return search_min($node->right);}#否则查找其父节点,直到当前节点是其父节点的左孩子$p = $node->parent;while ($p != null && $node == $p->right) {$node = $p;$p = $p->parent;}return $p;}#插入节点function insert_node($root, $node) {$cnode = $root;$p = $root;#查找合适的插入位置while ($cnode != null) {$p = $cnode;    if ($cnode->data > $node->data) {$cnode = $cnode->left;} else {$cnode = $cnode->right;}}if ($p == null) { #如果p为null,说明是空树$root = $node;} else {if ($p->data > $node->data) {$p->left = $node;} else {$p->right = $node;}$node->parent = $p;    }return $root;}#删除结点function delete_node($root, $dnode) {if ($dnode->left != null || $dnode->right != null) {$c = $dnode;} else {$c = successor($dnode);}if ($c->left != null) {$s = $c->left;} else {$s = $c->right;}if ($s != null) {$s->parent = $c->parent;}if ($c->parent == null) { #c是根节点$root = $s;} else if ($c == $c->parent->left) {$c->parent->left = $s; } else {$c->parent->right = $s;}if ($dnode != $c) {$dnode->data = $c->data;}return $root;}#使用数组建立二叉查找树function build_btree($a) {$root = new Node();$root->data= $a[0];for ($i = 1; $i < count($a); $i++) {$node = new Node();$node->data = $a[$i];insert_node($root, $node);}return $root;}#二叉树中序遍历function inorder_traverse($root) {if ($root->left != null) {inorder_traverse($root->left);}echo $root->data . " ";if ($root->right != null) {inorder_traverse($root->right);}}#链表的遍历function linked_list_traverse($head) {$node = $head;while ($node != null) {echo $node->data . " ";$node = $node->right;}}#二叉查找树变双向链表function change($root) {#如果有子节点,就往子节点递归,直到最后一个非叶子节点,将他们的左右子节点连接成链表#然后逐层往上递归if ($root->left != null) {btree_to_doublelist($root->left);#这里不用担心调整左右节点以后search_max查找出来的节点会出错,因为虽然调整以后树的结构变了,但是他依然保有二叉树的性质#看图1就知道了$predecessor = search_max($root->left);$predecessor->right = $root;$root->left = $predecessor;}if ($root->right != null) {btree_to_doublelist($root->right);$successor = search_min($root->right);$successor->left = $root;$root->right = $successor;}}function btree_to_doublelist($root) {#链表头节点就是二叉查找树的最小节点$head = search_min($root);change($root);return $head;}$a = array(10, 6, 14, 4, 8, 12, 16);$root = build_btree($a);inorder_traverse($root);echo "<br>";$link_head = btree_to_doublelist($root);linked_list_traverse($link_head);echo "<br>";
?>

4 6 8 10 12 14 16 
4 6 8 10 12 14 16

转载于:https://www.cnblogs.com/zemliu/archive/2012/09/26/2704881.html

PHP 将二叉查找树转换为双向链表,要求不能创建新节点,只能调节节点指针相关推荐

  1. 前序中序、后序中序遍历创建二叉树,并检验是否是二叉搜索树,若是则转换为双向链表

    finalbst.h //该程序的作用是根据所给的前序序列以及中序序列或者中序序列以及后序序列创建二叉树 #include <iostream> #include <vector&g ...

  2. 《程序员代码面试指南》第二章 链表问题 搜索二叉树转换为双向链表

    样例 树的中序遍历:1 2 3 4 5 6 7 ,转换后双向链表的遍历:1 2 3 4 5 6 7 java代码 /*** @Description:搜索二叉树转换为双向链表* @Author: li ...

  3. [二叉树]二叉搜索树转换为双向链表(剑指Offer26)

    [试题描述] 将二叉搜索树转换为双向链表 对于二叉搜索树,可以将其转换为双向链表,其中,节点的左子树指针在链表中指向前一个节点,右子树指针在链表中指向后一个节点. 思路一: 采用递归思想,对于二叉搜索 ...

  4. sketch 将动图转换为json_UI设计师如何创建sketch设计样式、库和UI套件

    使用Sketch来创建UI风格设计的样式,将受益匪浅.使用本教程构建UI套件,并同时创建自定义(可重复使用)库,以提高设计效率与质量. 无论是Sketch专家还是Sketch的新手,设计师都会发现:S ...

  5. 【IT笔试面试题整理】二叉搜索树转换为双向链表

    [试题描述] 将二叉搜索树转换为双向链表 对于二叉搜索树,可以将其转换为双向链表,其中,节点的左子树指针在链表中指向前一个节点,右子树指针在链表中指向后一个节点. 思路一: 采用递归思想,对于二叉搜索 ...

  6. arraylist扩容是创建新数组吗 java_Java 集合,你肯定也会被问到这些

    文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 作为一位小菜 "一面面试官",面试过程中,我肯定会问 Java 集合的内容,同时作为求职者,也肯定会 ...

  7. 服务器安装系统时无法创建新的分区,重装系统出现“我们无法创建新的分区,也找不到现有的分区”...

    今天给朋友的电脑重装系统,本来打算是使用微PE的CGI备份还原工具来给 C 盘重装一个系统,但是装完后重启无法进入系统. 不怕,以前也遇到过这种事情.根据经验我再次使用微PE,格式化 C 盘分区,找到 ...

  8. 安装程序无法创建新的系统分区也无法定位现有分区的解决方法

    2019独角兽企业重金招聘Python工程师标准>>> 在安装Windows7时,想必有很多人都安碰到这样的情况吧!在安装界面里选择安装时,却出现"安装程序无法创建新的系统 ...

  9. 《Python Cookbook 3rd》笔记(4.3):使用生成器创建新的迭代模式

    使用生成器创建新的迭代模式 问题 你想实现一个自定义迭代模式,跟普通的内置函数比如 range() , reversed() 不一样. 解法 如果你想实现一种新的迭代模式,使用一个生成器函数来定义它. ...

最新文章

  1. java中文getbytes为3,java 中文乱码问题
  2. Python编程基础:第四十五节 方法链Method Chaining
  3. 抛鸡蛋html5游戏,数学智力题:扔鸡蛋计算不会碎的楼层
  4. Nginx反代Mogilefs分布式储存示例
  5. ACM旗舰期刊最新综述:一览端到端人脸识别最新进展
  6. 【学习总结】GirlsInAI ML-diary day-7-数据类型转换
  7. jquery日期和时间的插件精确到秒
  8. PSPNet——Pyramid Scene Parsing Network
  9. MTK8788,6765,通用平台的按键驱动添加
  10. C++(opencv)简单拼接两幅图像
  11. 倍福电子凸轮实现案例展示
  12. 利用python制作马赛克图
  13. http协议文字加图解
  14. 笔记 09-集合(HashSet HashMap TreeMap) 练习
  15. Fluent Search
  16. ApacheCN 公众号文章汇总 2019.9
  17. Arduino UNO + 74HC595联级+数码管实现000-999循环计数显示+ Proteus仿真
  18. 几种负荷预测方法及其应用
  19. 一起来吐槽:来自暗网的公链项目VAS,竟然内含十级分销?
  20. 传奇自定义技能栏技术分享-GEE

热门文章

  1. sqlserver Conversion failed when converting the nvarchar to data type int
  2. HDOJ 1016 HDU 1016 Prime Ring Problem ACM 1016 IN HDU
  3. “theform._eventtarget 为空或者不是对象”,解决办法
  4. 网页左下角蒲公英动画
  5. 反编译android的apk
  6. 20161023 NOIP 模拟赛 T1 解题报告
  7. Java层与Jni层的数组传递(转)
  8. 9. Palindrome Number
  9. C# 工厂模式 简单入门
  10. php html自动打开新页面大小,HTML_html 用超链接打开新窗口其可控制窗口属性,1、html超链接打开的窗口大小 - phpStudy...