二叉树-数据结构

二叉树-数据结构

二叉树是属性结构的一个重要类型。
如下图二叉树形状
在这里插入图片描述

二叉树特征如下:
1.二叉树由 n(n >= 0) 个节点组成
2.如果 n 为 0,则为空树
3.如果 n = 1,则只有一个节点称为根节点(root)
4.每个节点最多有两个节点,节点分为左子树和右子树
5.所有左子树和右子树自身也必须是二叉树

如上图
节点6 是 跟节点 root
节点6 的左子树和右子树 分别是 节点4 和 节点8

名词概念:
节点:包含一个数据元素 及指向若干个子树 信息
节点的度:一个节点拥有子树的数量称为节点的度
叶子节点:也称为终端节点,没有子树的节点或者 度为零的节点
分支节点:也成非终端节点,有子树的节点或者 度不为零的节点
树的度:树中所有节点的度的最大值
树的层次:从根节点开始,假设根节点是第一层,根节点的子节点为第二层,一次类推,如果某一个节点位于第L层,则其子节点位于第 L+1层
树的深度:也成树的高度,树中所有节点的层次最大值称为树的深度
节点的深度:从根节点到节点的路径长度
节点的高度:从节点到其子树叶子节点最长的路径

二叉树的第 i 层上,最多有 2^(i - 1) 个节点,(i >= 1)
高度为 k 的二叉树,最多有 2^k - 1 个节点,(k >= 0)

完全二叉树
1.完全二叉树除了最低一层外,其他层都完全填充,最低层可能有空缺
2.最低一层的节点从左到右填充,空缺的节点只能在右边
3.对任一节点,如果其右子树的深度为j,则其左子树的深度必为j或j+1。 即度为1的点只有1个或0个
下图是一个完全二叉树
在这里插入图片描述

满二叉树
1.满二叉树每个非叶子结点都有两个子结点
2.叶子结点都位于树的最低层
3.满二叉树的每一层都完全填充,没有任何空缺
4.一个二叉树,如果每一层的节点数都达到最大值,则这个二叉树是满二叉树

如果一个满二叉树的层数为 k,则节点个数一定是 (2^k) - 1 个
下图是一个满二叉树
在这里插入图片描述
二叉树有下面几种遍历方式
先序遍历:遍历顺序为 根节点-> 左子树->右子树
中序遍历:遍历顺序为 左子树->根节点-> 右子树
后序遍历:遍历顺序为 左子树->右子树->根节点
层序遍历:按照层遍历,将一层所有的数据从左到右获取到,然后获取下一层

下面是C# 实现的二叉树,包含了上面几种遍历实现,这几种遍历的具体讲解看后续篇章

using System;

namespace DataStruct.BinTree
{
    /// <summary>
    /// 红黑树节点颜色枚举
    /// </summary>
    public enum Color
    {
        Red, 
        Black,
    }

    /// <summary>
    /// 二叉树节点定义
    /// </summary>
    /// <typeparam name="T">节点存储数据的类型</typeparam>
    public class BinNode<T> where T : IComparable<T>
    {
        // 节点值
        private T _element;
        // 父节点
        private BinNode<T> _parentNode;
        // 左子树
        private BinNode<T> _leftChild;
        // 右子树
        private BinNode<T> _rightChild;
        // 树高度
        private int _height;
        // 红黑树节点颜色
        private Color _color;

        public BinNode(T value)
        {
            _element = value;
        }

        public BinNode(T value, BinNode<T> parent)
        {
            _element = value;
            ParentNode = parent;
        }

        public BinNode<T> ParentNode
        {
            get { return _parentNode; }
            set { _parentNode = value; }
        }

        /// <summary>
        /// 获取左子树
        /// </summary>
        public BinNode<T> LeftChild
        {
            get { return _leftChild; }
            set { _leftChild = value; }
        }

        /// <summary>
        /// 获取右子树
        /// </summary>
        public BinNode<T> RightChild
        {
            get { return _rightChild; }
            set { _rightChild = value; }
        }

        /// <summary>
        /// 获取节点值
        /// </summary>
        public T Element
        {
            get { return _element; }
            set { _element = value; }
        }

        /// <summary>
        /// 获取树高度
        /// </summary>
        public int Height
        {
            get { return _height; }
            set { _height = value; }
        }

        /// <summary>
        /// 获取红黑树节点颜色
        /// </summary>
        public Color Color
        {
            get { return _color; }
            set { _color = value; }
        }

        /// <summary>
        /// 作为当前节点的左孩子插入新节点
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public BinNode<T> InsertAsLc(T t)
        {
            BinNode<T> leftChild = new BinNode<T>(t);
            return InsertAsLc(leftChild);
        }

        /// <summary>
        /// 作为当前节点的左孩子插入新节点
        /// </summary>
        /// <param name="leftChild"></param>
        /// <returns></returns>
        public BinNode<T> InsertAsLc(BinNode<T> leftChild)
        {
            _leftChild = leftChild;
            if (null != leftChild)
            {
                leftChild.ParentNode = this;
            }
            return _leftChild;
        }

        /// <summary>
        /// 作为当前节点的右孩子插入新节点
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public BinNode<T> InsertAsRc(T t)
        {
            BinNode<T> rightChild = new BinNode<T>(t);
            return InsertAsRc(rightChild);
        }

        /// <summary>
        /// 作为当前节点的右孩子插入新节点
        /// </summary>
        /// <param name="rightChild"></param>
        /// <returns></returns>
        public BinNode<T> InsertAsRc(BinNode<T> rightChild)
        {
            _rightChild = rightChild;
            if(null != rightChild)
            {
                rightChild.ParentNode = this;
            }
            return _rightChild;
        }

        /// <summary>
        /// 是否根节点
        /// </summary>
        /// <returns></returns>
        public bool IsRoot()
        {
            return null == ParentNode;
        }

        public bool HasParent()
        {
            return !IsRoot();
        }

        public bool HasLChild()
        {
            return null != LeftChild;
        }

        public bool HasRChild()
        {
            return null != RightChild;
        }

        /// <summary>
        /// 是父节点的左孩子
        /// </summary>
        /// <returns></returns>
        public bool IsLChild()
        {
            return !IsRoot() && this == ParentNode.LeftChild;
        }

        /// <summary>
        /// 是父节点的右孩子
        /// </summary>
        /// <returns></returns>
        public bool IsRChild()
        {
            return !IsRoot() && this == ParentNode.RightChild;
        }

        /// <summary>
        /// 有左子树或者右子树
        /// </summary>
        /// <returns></returns>
        public bool HasChild()
        {
            return HasLChild() || HasRChild();
        }

        /// <summary>
        /// 有左子树并且有右子树
        /// </summary>
        /// <returns></returns>
        public bool HasBoothChild()
        {
            return HasLChild() && HasRChild();
        }

        /// <summary>
        /// 是否叶子节点
        /// </summary>
        /// <returns></returns>
        public bool IsLeaf()
        {
            return !HasChild();
        }

        /// <summary>
        /// 是红黑树黑节点
        /// </summary>
        /// <returns></returns>
        public bool IsBlack()
        {
            return Color == Color.Black;
        }

        /// <summary>
        /// 是红黑树红节点
        /// </summary>
        /// <returns></returns>
        public bool IsRed()
        {
            return Color == Color.Red;
        }

        /// <summary>
        /// 重写 == 方法
        /// </summary>
        /// <param name="node1"></param>
        /// <param name="node2"></param>
        /// <returns></returns>
        public static bool operator == (BinNode<T> node1, BinNode<T> node2)
        {
            if (object.Equals(node1, null) || object.Equals(node2, null))
            {
                return object.Equals(node1, node2);
            }
            return node1.Element.CompareTo(node2.Element) == 0;
        }

        /// <summary>
        /// 重写 != 方法
        /// </summary>
        /// <param name="node1"></param>
        /// <param name="node2"></param>
        /// <returns></returns>
        public static bool operator != (BinNode<T> node1, BinNode<T> node2)
        {
            if (object.Equals(node1, null) || object.Equals(node2, null))
            {
                return !object.Equals(node1, node2);
            }
            return node1.Element.CompareTo(node2.Element) != 0;
        }

        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}

二叉树实现部分

    /// <summary>
    /// 二叉树
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BinTree<T> where T : IComparable<T>
    {
        private BinNode<T> _root = null;   // 跟节点

        public BinTree()
        {
            _root = null;
        }

        public BinNode<T> Root
        {
            get { return _root; }
            protected set { _root = value; }
        }

        public bool Empty()
        {
            return null == Root;
        }

        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public virtual bool Remove(BinNode<T> node)
        {
            if (node.IsRoot())
            {
                Root = null;
                return true;
            }
            
            if (node.IsLChild())
            {
                node.ParentNode.LeftChild = null;
            }
            else
            {
                node.ParentNode.RightChild = null;
            }

            UpdateHeightAbove(node.ParentNode);
            return true;
        }

        /// <summary>
        /// 清空树,并创建新的根节点
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public virtual BinNode<T> InsertAsRoot(T t)
        {
            _root = new BinNode<T>(t);
            UpdateHeightAbove(_root);
            return _root;
        }

        /// <summary>
        /// 作为当前节点的左孩子插入新节点
        /// </summary>
        /// <param name="node"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public virtual BinNode<T> InsertAsLc(BinNode<T> node, T t)
        {
            node.InsertAsLc(t);
            UpdateHeightAbove(node);
            return node.LeftChild;
        }

        /// <summary>
        /// 作为当前节点的右孩子插入新节点
        /// </summary>
        /// <param name="node"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public virtual BinNode<T> InsertAsRc(BinNode<T> node, T t)
        {
            node.InsertAsRc(t);
            UpdateHeightAbove(node);
            return node.RightChild;
        }

        #region Recursion
        /// <summary>
        /// 递归实现 先序遍历:跟节点->左子树->右子树
        /// </summary>
        /// <param name="node"></param>
        public void TraversePreRecursion(BinNode<T> node)
        {
            if (null == node)
            {
                return;
            }

            Console.Write(node.Element.ToString() + "    ");
            TraversePreRecursion(node.LeftChild);
            TraversePreRecursion(node.RightChild);
        }

        /// <summary>
        /// 递归实现 中序遍历:左子树->跟节点->右子树  递归实现
        /// </summary>
        /// <param name="node"></param>
        public void TraverseiInRecursion(BinNode<T> node)
        {
            if (null == node)
            {
                return;
            }

            TraverseiInRecursion(node.LeftChild);
            Console.Write(node.Element.ToString() + "    ");
            TraverseiInRecursion(node.RightChild);
        }

        /// <summary>
        /// 递归实现 后序遍历:左子树->右子树->跟节点
        /// </summary>
        /// <param name="node"></param>
        public void TraverseiPostRecursion(BinNode<T> node)
        {
            if (null == node)
            {
                return;
            }

            TraverseiPostRecursion(node.LeftChild);
            TraverseiPostRecursion(node.RightChild);
            Console.Write(node.Element.ToString() + "    ");
        }
        #endregion

        #region Iteration
        /// <summary>
        /// 迭代实现 先序遍历:跟节点->左子树->右子树
        /// </summary>
        /// <param name="node"></param>
        public void TraversePre(BinNode<T> node)
        {
            if (null == node)
            {
                return;
            }

            Stack<BinNode<T>> stack = new Stack<BinNode<T>>();
            stack.Push(node);
            while (stack.Count > 0)
            {
                node = stack.Pop();
                Console.Write(node.Element.ToString() + "    ");
                if (node.HasRChild())
                {
                    stack.Push(node.RightChild);
                }
                if(node.HasLChild())
                {
                    stack.Push(node.LeftChild);
                }
            }
        }

        /// <summary>
        /// 迭代实现 先序遍历:跟节点->左子树->右子树
        /// </summary>
        /// <param name="node"></param>
        public void TraversePre2(BinNode<T> node)
        {
            if (null == node)
            {
                return;
            }

            Stack<BinNode<T>> stack = new Stack<BinNode<T>>();
            stack.Push(node);
            while (stack.Count > 0)
            {
                while (null != node)
                {
                    Console.Write(node.Element.ToString() + "    ");
                    if ((node = node.LeftChild) != null)
                    {
                        stack.Push(node);
                    }
                }

                node = stack.Pop();
                if (null != node && ((node = node.RightChild) != null))
                {
                    stack.Push(node);
                }
            }
        }

        /// <summary>
        /// 迭代实现 中序遍历:左子树->跟节点->右子树
        /// </summary>
        /// <param name="node"></param>
        public void TraverseIn(BinNode<T> node)
        {
            if (null == node)
            {
                return;
            }

            Stack<BinNode<T>> stack = new Stack<BinNode<T>>();
            stack.Push(node);
            while (stack.Count > 0)
            {
                while (null != node)
                {
                    if ((node = node.LeftChild) != null)
                    {
                        stack.Push(node);
                    }
                }

                node = stack.Pop();
                Console.Write(node.Element.ToString() + "    ");
                if (null != node && ((node = node.RightChild) != null))
                {
                    stack.Push(node);
                }
            }
        }

        /// <summary>
        /// 迭代实现 后序遍历:左子树->右子树->跟节点
        /// </summary>
        /// <param name="node"></param>
        public void TraversePost(BinNode<T> node)
        {
            if (null == node)
            {
                return;
            }

            Stack<BinNode<T>> result = new Stack<BinNode<T>>();
            Stack<BinNode<T>> stack = new Stack<BinNode<T>>();
            stack.Push(node);
            while (stack.Count > 0)
            {
                node = stack.Pop();
                result.Push(node);
                if (node.HasLChild())
                {
                    stack.Push(node.LeftChild);
                }
                if (node.HasRChild())
                {
                    stack.Push(node.RightChild);
                }
            }

            while (result.Count > 0)
            {
                BinNode<T> temp = result.Pop();
                Console.Write(temp.Element.ToString() + "    ");
            }

            Console.WriteLine();
        }

        //、层序遍历:按层从上到下,每层从左到右依次遍历
        public List<BinNode<T>> TraverseLevel(BinNode<T> node)
        {
            List<BinNode<T>> list = new List<BinNode<T>>();
            if (null == node)
            {
                return list;
            }

            Queue<BinNode<T>> queue = new Queue<BinNode<T>>();
            queue.Enqueue(node);
            while (queue.Count > 0)
            {
                node = queue.Dequeue();
                Console.Write(node.Element.ToString() + "   ");
                list.Add(node);
                if (node.HasLChild())
                {
                    queue.Enqueue(node.LeftChild);
                }
                if (node.HasRChild())
                {
                    queue.Enqueue(node.RightChild);
                }
            }
            return list;
        }
        #endregion

        /// <summary>
        /// 更新树高度
        /// </summary>
        /// <param name="node"></param>
        protected void UpdateHeightAbove(BinNode<T> node)
        {
            while (null != node) // 从node出发,覆盖历代祖先
            {
                UpdateHeight(node);
                node = node.ParentNode;
            }
        }

        /// <summary>
        /// 更新树高度
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected virtual int UpdateHeight(BinNode<T> node)
        {
            node.Height = 1 + Math.Max(NodeHeight(node.LeftChild), NodeHeight(node.RightChild));
            return node.Height;
        }

        /// <summary>
        /// 后去节点的高度
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected int NodeHeight(BinNode<T> node)
        {
            return (null != node) ? node.Height : -1;
        }

        public virtual void Release()
        {
            _root = null;
        }
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值