C# 二叉树的实现

二叉树的创建:

namespace BinaryTree
{
    /// <summary>
    /// 二叉树的存储结构类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Node<T> 
    {
        public T Data { get; set; } //数据域(结点数据)
        public Node<T> LeftChild { get; set; } //左孩子
        public Node<T> RightChild { get; set; } //右孩子

        //构造器
        public Node(T value, Node<T> lChild, Node<T> rChild)
        {
            this.Data = value;
            this.LeftChild = lChild;
            this.RightChild = rChild;
        }

        //构造器
        public Node(Node<T> lChild, Node<T> rChild)
        {
            this.Data = default(T);
            this.LeftChild = lChild;
            this.RightChild = rChild;
        }

        //构造器
        public Node(T value)
        {
            this.Data = value;
            this.LeftChild = null;
            this.RightChild = null;
        }
    }

    /// <summary>
    /// 不带头结点的二叉树的二叉链表的类 BiTree<T>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BiTree<T>
    {
        public Node<T> Head{get;set;}  //头引用

        //构造器
        public BiTree()
        {
            this.Head = null;
        }

        //构造器
        public BiTree(T value)
        {
            Node<T> p = new Node<T>(value);
            this.Head = p;
        }

        //构造器
        public BiTree(T val, Node<T> lp, Node<T> rp)
        {
            Node<T> p = new Node<T>(val, lp, rp);
            this.Head = p;
        }

         //判断是否是空二叉树
        public bool IsEmpty()
        {
            if(this.Head ==null)
                return true;
            else
                return false;
        }

          //获取根结点
        public Node<T> Root()
        {
            return this.Head;
        }

        /// <summary>
        /// 获取结点的左孩子结点
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public Node<T> GetLeftChild(Node<T> p)
        {
            return p.LeftChild;
        }

        /// <summary>
        /// 获取结点的右孩子结点
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public Node<T> GetRightChild(Node<T> p)
        {
            return p.RightChild;
        }

        /// <summary>
        /// 将结点p的左子树插入值为 val的新结点.
        /// 原来的左子树成为新结点的左子树.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="p"></param>
        public void InsertLeftChild(T value,Node<T> p)
        {
            Node<T> temp = new Node<T>(value);
            temp.LeftChild = p.LeftChild;
            p.LeftChild = temp;

        }

        
        //将结点p的右子树插入值为 val的新结点,
        //原来的右子树成为新结点的右子树.
        public void InsertRightChild(T value, Node<T> p)
        {
            Node<T> temp = new Node<T>(value);
            //原来的右子树成为新结点的右子树
            temp.RightChild = p.RightChild;
            //p的右孩子为新结点
            p.RightChild = temp; 
        }

        /// <summary>
        /// 若 p 非空, 删除 p 的左子树
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public Node<T> DeleteLeft(Node<T> p)
        {
            if(p ==null || p.LeftChild ==null)
            {
                return null;
            }
            Node<T> temp = p.LeftChild;
            temp.LeftChild = null;
            return temp;
        }

        /// <summary>
        /// 若 p 非空, 删除 p 的右子树
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public Node<T> DeleteRight(Node<T> p)
        {
            if ((p == null) || (p.RightChild == null))
            {
                return null;
            }
 
            Node<T> temp = p.RightChild;
            p.RightChild = null;
            return temp;
        }

        /// <summary>
        /// 判断是否是叶子结点
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool IsLeaf(Node<T> p)
        {
            if ((p != null) && (p.LeftChild == null) && (p.RightChild == null))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
 
        //树的遍历: 由于树的定义是递归的,
        //所以遍历算法也彩递归实现
        //原始顺序为: A B C D E F G H I J
        //(原则是 从小到下, 从左到右)
        //1.先序遍历(DLR), 思想是: 首先访问根结点,
        //然后先序遍历其左子树, 最后先遍历其右子树.
        //结果是: A B D H I E J C F G
        public void PreOrder(Node<T> root)
        {
            //根结点为空
            if (root == null)
            {
                return;
            }
 
            //第一步: 处理根结点
            Console.WriteLine("{0}", root.Data);
            //第二步: 遍历左子树
            PreOrder(root.LeftChild);
            //第三步: 遍历右子树
            PreOrder(root.RightChild);
        }

          //中序遍历(LDR), 思想是: 首先中序遍历结点的左子树,
        //然后访问根结点, 最后中序遍历其右子树
        //结果为: H DI B E J E A F C G
        public void InOrder(Node<T> root)
        {
            //根结点为空
            if (root == null)
            {
                return;
            }
            //中序遍历左子树
            InOrder(root.LeftChild);
            //处理根结点,注: 这时的根结点指每一个可以作为父结点的结点.
            Console.WriteLine("{0}", root.Data);
            //中序遍历右子树.
            InOrder(root.RightChild);
        }

         //后序遍历(LRD): 基本思想是: 首先遍历根结点的左子树,
        //然后后后序遍历根结点的右子树, 最后访问根结点
        //结果为:  H I D J E B F G C A
        public void PostOrder(Node<T> root)
        {
            //根结点为空
            if (root == null)
            {
                return;
            }
            //后序遍历左子树
            PostOrder(root.LeftChild);
            //后序遍历右子树
            PostOrder(root.RightChild);
            //处理根结点
            Console.WriteLine("{0}", root.Data);
 
        }

        //(4).层序遍历(Level Order)
        //思想: 由于层次遍历结点的顺序是先遇到的结点先访问,
        //与队列操作的顺序相同.
        //所以, 在进行层次遍历时, 设置一个队列, 将根结点引用入队,
        //当队列非空时, 循环执行以下三步:
        //(1).从队列中取出一个结点引用, 并访问该结点.
        //(2).若该结点的左子树非空, 将该结点的左子树引用入队;
        //(3).若该结点的右子树非空, 将该结点的右子树引用入队;
        public void LevelOrder(Node<T> root)
        {
            //根结点为空
            if (root == null)
            {
                return;
            }
 
            //设置一个队列保存层序遍历的结点
            //...此处需要引用到队列的定义类与操作类, 暂略.
        }

    }

}


    class Program
    {
        static void Main(string[] args)
        {
            Node<string>[] node = new Node<string>[8];
            //建立结点
            node[0] = new Node<string>("A");
            node[1] = new Node<string>("B");
            node[2] = new Node<string>("C");
            node[3] = new Node<string>("D");
            node[4] = new Node<string>("E");
            node[5] = new Node<string>("F");
            node[6] = new Node<string>("G");
            node[7] = new Node<string>("H");
            //运用层次遍历二叉树的思想,构造一个已知的二叉树 

            BiTree<string>[] biTree = new BiTree<string>[8];
            biTree[0] = new BiTree<string>("R");  //根结点
            biTree[0].Head.LeftChild = node[0];
            biTree[0].Head.RightChild = node[1];
            biTree[1] = new BiTree<string>("r1");
            biTree[1].Head.LeftChild = node[2];
            biTree[1].Head.RightChild = node[3];
            biTree[2] = new BiTree<string>("r2");
            biTree[2].Head.LeftChild = node[4];
            biTree[2].Head.RightChild = node[5];
            biTree[3] = new BiTree<string>("r3");
            biTree[3].Head.LeftChild = node[6];
            biTree[3].Head.RightChild = node[7];
            //biTree[3].Head.RightChild = biTree[6].Head;
            //biTree[4].Head.RightChild = biTree[7].Head;
            biTree[0].InOrder(biTree[1].Head);

            Console.Read();
        }
    }


参考:http://www.csharpwin.com/csharpspace/2412.shtml

http://www.cnblogs.com/ppchouyou/archive/2008/07/18/1245819.html

http://tech.sina.com.cn/s/2008-06-20/1017701850.shtml

http://www.yqdown.com/chengxukaifa/CC/28584_3.htm


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值