当前位置: 首页 > news >正文

面试毒瘤 之 反转二叉树

前一阵homebrew作者面试谷歌被拒,原因之一是这位老兄无法反转出二叉树。

 

既然众公司面试都爱用这货面试,咱也来做一下。

 

先定义二叉树类

    public class BinaryTreeNode<T>
    {
        public string Name { get; set; }
        public T Data { get; set; }
        public BinaryTreeNode<T> Left { get; set; }
        public BinaryTreeNode<T> Right { get; set; }
        private bool _isLeaf;
        public bool IsLeaf
        {
            get
            {
                _isLeaf = (Left == null && Right == null);
                return _isLeaf;
            }
        }
        public BinaryTreeNode(string name, T data = default(T))
        {
            Name = name;
            Data = data;
        }
        public BinaryTreeNode<T> CreateAndJionLeft(string name, T data = default(T))
        {
            return Left = new BinaryTreeNode<T>(name, data);
        }
        public BinaryTreeNode<T> CreateAndJionRight(string name, T data = default(T))
        {
            return Right = new BinaryTreeNode<T>(name, data);
        }
    }

Name和Data是二叉树内部元素,根据需求调整即可,CreateAndJionLeft表示将左边子节点加入当前节点,也可在外部调用端实例化子节点。

 

接下来是二叉树常用的几种遍历方式:前序遍历,中序遍历,后序遍历,逐层遍历

        /// <summary>
        /// 前序遍历
        /// </summary>
        public void PreOrderTraversal()
        {
            if (this != null)
            {
                Trace.WriteLine(Name);
            }
            if (Left != null)
            {
                Left.PreOrderTraversal();
            }
            if (Right != null)
            {
                Right.PreOrderTraversal();
            }
        }
        /// <summary>
        /// 前序遍历 非递归
        /// </summary>
        public void PreOrderTraversalEx()
        {
            Stack<BinaryTreeNode<T>> stack = new Stack<BinaryTreeNode<T>>();
            BinaryTreeNode<T> node = this;
            while (node != null || stack.Count != 0)
            {
                while (node != null)
                {
                    Trace.WriteLine(node.Name);
                    stack.Push(node);
                    node = node.Left;
                }
                if (stack.Count != 0)
                {
                    node = stack.Pop();
                    node = node.Right;
                }
            }
        }

        /// <summary>
        /// 中序遍历
        /// </summary>
        public void InOrderTraversal()
        {
            if (Left != null)
            {
                Left.InOrderTraversal();
            }
            if (this != null)
            {
                Trace.WriteLine(Name);
            }
            if (Right != null)
            {
                Right.InOrderTraversal();
            }
        }
        /// <summary>
        /// 中序遍历 非递归
        /// </summary>
        public void InOrderTraversalEx()
        {
            Stack<BinaryTreeNode<T>> stack = new Stack<BinaryTreeNode<T>>();
            BinaryTreeNode<T> node = this;
            while (node != null || stack.Count != 0)
            {
                while (node != null)
                {
                    stack.Push(node);
                    node = node.Left;
                }
                if (stack.Count != 0)
                {
                    node = stack.Peek();
                    stack.Pop();
                    Trace.WriteLine(node.Name);
                    node = node.Right;
                }
            }
        }

        /// <summary>
        /// 后序遍历
        /// </summary>
        public void PostOrderTraversal()
        {
            if (Left != null)
            {
                Left.PostOrderTraversal();
            }
            if (Right != null)
            {
                Right.PostOrderTraversal();
            }
            if (this != null)
            {
                Trace.WriteLine(Name);
            }
        }
        /// <summary>
        /// 后序遍历 非递归
        /// </summary>
        public void PostOrderTraversalEx()
        {
            Stack<BinaryTreeNode<T>> stack = new Stack<BinaryTreeNode<T>>();
            BinaryTreeNode<T> node = this;
            BinaryTreeNode<T> lastNode = null;
            stack.Push(node);
            while (stack.Count!=0)
            {
                node = stack.Peek();
                if ((node.Left == null && node.Right == null) || (lastNode != null && (lastNode == node.Left || lastNode == node.Right)))
                {
                    //如果当前结点没有子结点或者子节点都已被访问过就输出  因为后序遍历是先子节点再根节点
                    Trace.WriteLine(node.Name);
                    stack.Pop();
                    lastNode = node;//设定本次访问的节点为上一次访问的节点
                }
                else
                {
                    if (node.Right != null)
                        stack.Push(node.Right);
                    if (node.Left != null)
                        stack.Push(node.Left);
                }
            }
        }

        /// <summary>
        /// 逐层遍历
        /// </summary>
        public void Traversal()
        {
            Stack<BinaryTreeNode<T>> stack = new Stack<BinaryTreeNode<T>>();
            stack.Push(this);
            while (stack.Count > 0)
            {
                BinaryTreeNode<T> temp = stack.Peek();
                Trace.WriteLine(temp.Name);
                stack.Pop();
                if (temp.Left != null)
                {
                    stack.Push(temp.Left);
                }
                if (temp.Right != null)
                {
                    stack.Push(temp.Right);
                }
            }
        }

 

递归实现反转二叉树

        /// <summary>
        /// 反转二叉树(递归)
        /// </summary>
        public BinaryTreeNode<T> ReverseWithRecursive()
        {
            if (this == null)
            {
                return null;
            }

            if (!(Left == null && Right == null))
            {
                BinaryTreeNode<T> temp = Right;//左右节点反转
                Right = Left;
                Left = temp;

                if (Left != null)
                    Left = Left.ReverseWithRecursive();//递归反转左子节点
                if (Right != null)
                    Right = Right.ReverseWithRecursive();//递归反转右子节点
            }
            return this;
        }

 

非递归方式实现反转二叉树

     /// <summary>
        /// 反转二叉树(非递归)
        /// </summary>
        /// <returns></returns>
        public BinaryTreeNode<T> Reverse()
        {
            if (this == null)
            {
                return null;
            }

            Queue<BinaryTreeNode<T>> nodeQueue = new Queue<BinaryTreeNode<T>>();
            nodeQueue.Enqueue(this);
            while (nodeQueue.Count > 0)
            {
                BinaryTreeNode<T> node = nodeQueue.Peek();
                nodeQueue.Dequeue();

                BinaryTreeNode<T> tempNode = node.Right;//左右节点反转
                node.Right = node.Left;
                node.Left = tempNode;

                if (node.Left != null)
                {
                    nodeQueue.Enqueue(node.Left);
                }
                if (node.Right != null)
                {
                    nodeQueue.Enqueue(node.Right);
                }
            }
            return this;
        }

定义一个队列来临时存储即将反转的节点。获取队列中存储的节点,获取到一个节点后队列中的此节点已无用将其删除,然后把获取到的节点的左右子节点反转,将反转后的左右子节点都放入队列用于下一次循环。重复执行直到反转完所有树节点。

 

换成栈存储

        /// <summary>
        /// 反转二叉树(非递归) 栈
        /// </summary>
        /// <returns></returns>
        public BinaryTreeNode<T> ReverseEx()
        {
            if (this == null)
            {
                return null;
            }

            Stack<BinaryTreeNode<T>> nodeStack = new Stack<BinaryTreeNode<T>>();
            nodeStack.Push(this);
            while (nodeStack.Count > 0)
            {
                BinaryTreeNode<T> node = nodeStack.Peek();
                nodeStack.Pop();

                BinaryTreeNode<T> tempNode = node.Right;//左右节点反转
                node.Right = node.Left;
                node.Left = tempNode;

                if (node.Left != null)
                {
                    nodeStack.Push(node.Left);
                }
                if (node.Right != null)
                {
                    nodeStack.Push(node.Right);
                }
            }
            return this;
        }

 

 

客户端调用

            //创建二叉树
            BinaryTreeNode<int> tree = new BinaryTreeNode<int>("0");//rootNode
            BinaryTreeNode<int> n01 = tree.CreateAndJionLeft("01");
            BinaryTreeNode<int> n02 = tree.CreateAndJionRight("02");
            BinaryTreeNode<int> n011 = n01.CreateAndJionLeft("011");
            BinaryTreeNode<int> n012 = n01.CreateAndJionRight("012");
            BinaryTreeNode<int> n021 = n02.CreateAndJionLeft("021");
            BinaryTreeNode<int> n0211 = n021.CreateAndJionLeft("0211");
            BinaryTreeNode<int> n0212 = n021.CreateAndJionRight("0212");

            //遍历输出
            tree.Traversal();

            //反转二叉树并遍历输出
            BinaryTreeNode<int> treeReverse = tree.Reverse();
            treeReverse.Traversal();

反转前

 

反转后

 

转载请注明地址:http://www.cnblogs.com/wintersoft/p/4676124.html

转载于:https://www.cnblogs.com/wintersoft/articles/4676124.html

相关文章:

  • STM32串口寄存器操作(转)
  • (剑指Offer)面试题41:和为s的连续正数序列
  • html 7.28
  • 每天一个Linux命令—— WC
  • const的作用
  • 重置 Launchpad 和更新APP图标缓存
  • (算法)求1到1亿间的质数或素数
  • java程序设计之完数
  • css 多行显示省略号....
  • python--参数列表的分拆
  • EL表达式从request和session中取值
  • 经典图论500题
  • 下拉列表框实现二级联动
  • 修改乱码的方法
  • 微信网站注意事项
  • [数据结构]链表的实现在PHP中
  • avalon2.2的VM生成过程
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • extract-text-webpack-plugin用法
  • js ES6 求数组的交集,并集,还有差集
  • JSDuck 与 AngularJS 融合技巧
  • JS字符串转数字方法总结
  • Making An Indicator With Pure CSS
  • spring + angular 实现导出excel
  • SSH 免密登录
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • Wamp集成环境 添加PHP的新版本
  • 阿里研究院入选中国企业智库系统影响力榜
  • 半理解系列--Promise的进化史
  • 给Prometheus造假数据的方法
  • 关于Flux,Vuex,Redux的思考
  • 力扣(LeetCode)21
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 一份游戏开发学习路线
  • 找一份好的前端工作,起点很重要
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • ​如何在iOS手机上查看应用日志
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #NOIP 2014# day.1 T2 联合权值
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (31)对象的克隆
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (力扣)循环队列的实现与详解(C语言)
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (四)汇编语言——简单程序
  • (转)大型网站的系统架构
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .dwp和.webpart的区别
  • .net core 连接数据库,通过数据库生成Modell
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .Net程序帮助文档制作
  • .net连接oracle数据库