C# 创建以及操作二叉树

这是我用C#编写的关于二叉树的一个类,它是一个Windows程序的一部分(用于图形化显示一棵二叉树,并能插入、寻找、删除任意节点,最后还可以将一棵非平衡的二叉树平衡化)。

    下面仅对其中的两个函数做下说明:   
    private void Insert(TreeNode root, int num)    //用一般的要求建立一棵二叉树
    private TreeNode AVLTreeInsertNode(int num, ref TreeNode root)    //按照动态平衡的要求建立一棵二叉树


using System.Drawing; 
using System.Collections; 
 
namespace nsBinaryTree 

    // 定义树节点类 
    public class TreeNode 
    { 
        private int data;    // 节点数据 
        public TreeNode left_child;     // 左子女 
        public TreeNode right_child;    // 右子女 
        public TreeNode parent;        // 父节点 
 
        // 节点在树中的高度,平衡处理时,用节点在树中的高度代替平衡因子 
        public int Height; 
         
        // data访问器 
        public int Data 
        { 
            get 
            { 
                return data; 
            } 
            set 
            { 
                data = value; 
            } 
        } 
 
        // 左子女访问器 
        public TreeNode LeftChild 
        { 
            get 
            { 
                return left_child; 
            } 
            set 
            { 
                left_child = value; 
            } 
        } 
 
        // 右子女访问器 
        public TreeNode RightChild 
        { 
            get 
            { 
                return right_child; 
            } 
            set 
            { 
                right_child = value; 
            } 
        } 
 
        // 父节点访问器 
        public TreeNode Parent 
        { 
            get 
            { 
                return parent; 
            } 
            set 
            { 
                parent = value; 
            } 
        }      
 
        // 构造函数,初始化左右子女为空 
        public TreeNode() 
        { 
            data = 0; 
            left_child = null; 
            right_child = null;
         parent = null; 
        } 
    } 
 
    // 定义二叉树类 
    public class BinaryTree 
    { 
        public TreeNode root;    //根节点 
 
        // 根节点的访问器 
        public TreeNode Root 
        { 
            get 
            { 
                return root; 
            } 
            set 
            { 
                root = value; 
            } 
        } 
 
        // 构造函数 
        public BinaryTree() 
        { 
            root = null; 
        } 
 
        // 判断树是否为空 
        public bool IsNullOrEmpty() 
        { 
            if (root == null) 
            { 
                return true; 
            } 
            else 
            { 
                return false; 
            } 
        }         
 
        // Insert a node to the tree. 
        public void Insert(int num) 
        { 
            if (root == null) 
            { 
                root = new TreeNode(); 
                root.Data = num; 
                root.parent = null; 
            } 
            else 
            { 
                Insert(root, num); 
            } 
        } 
 
        // 插入元素,重载函数 
        private void Insert(TreeNode root, int num) 
        { 
            if (num == root.Data) 
            { 
                return; 
            } 
            else if (num < root.Data) 
            { 
                if (root.LeftChild == null) 
                { 
                    TreeNode temp_node = new TreeNode(); 
                    temp_node.Data = num; 
                    temp_node.Parent = root; 
 
                    root.LeftChild = temp_node; 
                } 
                else 
                { 
                    Insert(root.LeftChild, num); 
                } 
            } 
            else 
            { 
                if (root.RightChild == null) 
                { 
                    TreeNode temp_node = new TreeNode(); 
                    temp_node.Data = num; 
                    temp_node.Parent = root; 
 
                    root.RightChild = temp_node; 
                } 
                else 
                { 
                    Insert(root.RightChild, num); 
                } 
            } 
        } 
 
        // 查找是否存在某一个数值,如果存在,返回该节点,否则返回null 
        public TreeNode Search(int num) 
        { 
            TreeNode searched_node = new TreeNode(); 
            searched_node = Search(root, num); 
            return searched_node; 
        } 
 
        // 查找是否存在该元素,重载函数 
        private TreeNode Search(TreeNode root, int num) 
        { 
            TreeNode searched_node = new TreeNode(); 
 
            if (root.Data == num) 
            { 
                searched_node = root; 
            } 
            else 
            { 
                if (num < root.Data) 
                { 
                    if (root.LeftChild != null) 
                    { 
                        searched_node = Search(root.LeftChild, num); 
                    } 
                } 
                else 
                { 
                    if (root.RightChild != null) 
                    { 
                        searched_node = Search(root.RightChild, num); 
                    } 
                } 
            } 
 
            return searched_node; 
        } 
 
        // 遍历二叉树,从而设置其所有节点的Brush属性为默认值 
        public void SetTreeNodeBrush() 
        { 
            SetTreeNodeBrush(root); 
        } 
 
        // 前序遍历,重载函数 
        private void SetTreeNodeBrush(TreeNode root) 
        { 
            if (root != null) 
            { 
                // TODO: 添加遍历要做的事,比如我希望在PictureBox中绘制节点,那么可以在这里设置节点的画刷属性:
               //root.Brush = new SolidBrush(Color.Turquoise);    //重新设置节点的画刷 
 
                if (root.LeftChild != null) 
                { 
                    SetTreeNodeBrush(root.LeftChild); 
                } 
                 
                if (root.RightChild != null) 
                { 
                    SetTreeNodeBrush(root.RightChild); 
                }             
            } 
        } 
 
        // 获得该节点最小右子女(另一种方法是取它的最大左子女),用于删除节点 
        TreeNode MinRightChild(TreeNode parent) 
        { 
            TreeNode temp = parent; 
            while (temp != null) 
            { 
                if (temp.LeftChild == null) 
                { 
                    return temp; 
                } 
                else 
                { 
                    temp = temp.LeftChild;  
                } 
            } 
 
            return null; 
        } 
          
        // 删除节点 
        public void DeleteNode(int num) 
        { 
            if (root == null) 
            { 
                return; 
            }  
            else if(root.Data == num) 
            { 
                TreeNode tmp = MinRightChild(root.RightChild); 
                if(tmp == null) 
                { 
                    root = root.LeftChild; 
                } 
                else 
                { 
                    root.Data = tmp.Data; 
                    DeleteNode(root, root.RightChild, 1, tmp.Data); 
                } 
            } 
            else if (root.Data < num) 
            { 
                DeleteNode(root, root.RightChild, 1, num); 
            } 
            else 
            { 
                DeleteNode(root, root.LeftChild, 0, num); 
            }      
        } 
 
        // 删除节点,重载函数 
        private void DeleteNode(TreeNode parent, TreeNode cur, int direction, int num) 
        { 
            if (cur.Data == num) 
            { 
                if (cur.LeftChild == null) 
                { 
                    if (direction == 0) 
                    { 
                        parent.LeftChild = cur.RightChild; 
                    } 
                    else 
                    { 
                        parent.RightChild = cur.RightChild; 
                    } 
                } 
                else if (cur.RightChild == null) 
                { 
                    if (direction == 0) 
                    { 
                        parent.LeftChild = cur.LeftChild; 
                    } 
                    else 
                    { 
                        parent.RightChild = cur.LeftChild; 
                    } 
                } 
                else 
                { 
                    TreeNode tmp = MinRightChild(cur.RightChild); 
                    cur.Data = tmp.Data; 
                    DeleteNode(cur, cur.RightChild, 1, tmp.Data); 
                } 
            } 
            else if (cur.Data > num) 
            { 
                DeleteNode(cur, cur.LeftChild, 0, num); 
            } 
            else 
            { 
                DeleteNode(cur, cur.RightChild, 1, num); 
            } 
        } 
 
        // 求树的深度 
        private int TreeHeight(TreeNode root) 
        { 
            if (root == null) 
            { 
                return 0; 
            } 
            else 
            { 
                int left_depth = TreeHeight(root.left_child); 
                int right_depth = TreeHeight(root.right_child); 
 
                if (left_depth > right_depth) 
                { 
                    return left_depth + 1; 
                } 
                else 
                { 
                    return right_depth + 1; 
                } 
            } 
        } 
 
        // 判断一棵树是否为平衡二叉树 
        public bool IsBalance() 
        { 
            return IsBalance(root); 
        } 
 
        //  判断一棵树是否为平衡二叉树,重载函数 
        private bool IsBalance(TreeNode root) 
        { 
            if (root == null) 
            { 
                return true; 
            } 
 
            int dis = TreeHeight(root.left_child) - TreeHeight(root.right_child); 
 
            if (dis > 1 || dis < -1) 
            { 
                return false; 
            } 
            else 
            { 
                return IsBalance(root.left_child) && IsBalance(root.right_child); 
            } 
        } 
 
        // 平衡二叉树 
        public void Balance() 
        { 
            Balance(ref root); 
        } 
 
        // 平衡二叉树,重载函数 
        // 大体过程:先将树的所有节点Data值存入到一个数组中,然后再按照平衡二叉树的要求逐个插入Data,从而得到平衡二叉树 
        private void Balance(ref TreeNode root) 
        { 
            if (this.IsBalance() == true)    // 判断树是否已经平衡 
            { 
                return; 
            } 
            else 
            { 
                ArrayList array_list = new ArrayList(); 
                SaveTreeNode(root, array_list);    //将树内所有结点的Data值存入到一个ArrayList中 
          
                BinaryTree btree = new BinaryTree(); 
                for (int i = 0; i < array_list.Count; i++) 
                { 
                    root = AVLTreeInsertNode((int)array_list[i], ref btree.root); 
                } 
            } 
        } 
 
        // 通过前序遍历的方式,将树内所有结点的Data值存入到一个ArrayList中,为建立平衡二叉树做准备 
        private void SaveTreeNode(TreeNode root, ArrayList array_list) 
        { 
            if (root != null) 
            { 
                array_list.Add(root.Data); 
 
                if (root.left_child != null) 
                { 
                    SaveTreeNode(root.left_child, array_list); 
                } 
 
                if (root.right_child != null) 
                { 
                    SaveTreeNode(root.right_child, array_list); 
                } 
            } 
        } 
         
        // 按平衡二叉树的要求插入节点 
        private TreeNode AVLTreeInsertNode(int num, ref TreeNode root) 
        { 
            if (root == null) 
            { 
                root = new TreeNode(); 
                root.Data = num; 
                root.Height = 0; 
                root.left_child = root.right_child = null; 
            } 
            else if (num < root.Data)    // 插入到左子树中 
            { 
                root.left_child = AVLTreeInsertNode(num, ref root.left_child); 
                if (TreeHeight(root.left_child) - TreeHeight(root.right_child) == 2)    // AVL树不平衡 
                { 
                    if (num < root.left_child.Data) 
                    { 
                        root = SingleRotateWithLeft(root);    // 插入到了左子树左边, 做单旋转 
                    } 
                    else 
                    { 
                        root = DoubleRotateWithLeft(root);    // 插入到了左子树右边, 做双旋转 
                    } 
                } 
            } 
            else if (num > root.Data)    // 插入到右子树中 
            { 
                root.right_child = AVLTreeInsertNode(num, ref root.right_child); 
                if (TreeHeight(root.right_child) - TreeHeight(root.left_child) == 2)    // AVL树不平衡 
                { 
                    if (num > root.right_child.Data) 
                    { 
                        root = SingleRotateWithRight(root);    // 插入到了右子树右边, 做单旋转 
                    } 
                    else 
                    { 
                        root = DoubleRotateWithRight(root);    // 插入到了右子树左边, 做双旋转 
                    } 
                } 
            } 
 
            root.Height = Max(TreeHeight(root.left_child), TreeHeight(root.right_child)) + 1; 
 
            return root; 
        } 
 
        // 左单旋转 
        private TreeNode SingleRotateWithLeft(TreeNode root) 
        { 
            TreeNode node = new TreeNode(); 
 
            node = root.left_child; 
            root.left_child = node.right_child; 
            node.right_child = root; 
 
            // 结点的位置改变了, 更新其高度值 
            root.Height = Max(TreeHeight(root.left_child), TreeHeight(root.right_child)) + 1; 
            node.Height = Max(TreeHeight(node.left_child), root.Height) + 1; 
 
            return node; 
        } 
 
        // 右单旋转 
        private TreeNode SingleRotateWithRight(TreeNode root) 
        { 
            TreeNode node = new TreeNode(); 
 
            node = root.right_child; 
            root.right_child = node.left_child; 
            node.left_child = root; 
 
            // 结点的位置改变了, 更新其高度值 
            root.Height = Max(TreeHeight(root.left_child), TreeHeight(root.right_child)) + 1; 
            node.Height = Max(TreeHeight(node.right_child), root.Height) + 1; 
 
            return node; 
        } 
 
        // 先左后右双旋转 
        private TreeNode DoubleRotateWithLeft(TreeNode root) 
        { 
            root.left_child = SingleRotateWithRight(root.left_child); 
            return SingleRotateWithLeft( root); 
        } 
 
        // 先右后左双旋转 
        private TreeNode DoubleRotateWithRight(TreeNode root) 
        { 
            root.right_child = SingleRotateWithLeft(root.right_child); 
            return SingleRotateWithRight(root); 
        } 
 
        // 求两个整数中较大的数 
        private int Max(int a, int b) 
        { 
            return a > b ? a : b; 
        } 
 
        // 删除树 
        public void DeleteTree() 
        { 
            DeleteTree(ref root); 
        } 
 
        // 删除树,重载函数 
        private void DeleteTree(ref TreeNode root) 
        { 
            if (root != null) 
            { 
                if (root.LeftChild != null) 
                { 
                    DeleteTree(ref root.left_child); 
                } 
                if (root.RightChild != null) 
                { 
                    DeleteTree(ref root.right_child); 
                } 
 
                if (root.LeftChild != null && root.Parent != null) 
                { 
                    root.Parent.left_child = null; 
                } 
 
                if (root.RightChild != null && root.Parent != null) 
                { 
                    root.Parent.right_child = null; 
                }  
                 
                root = null;  
            }           
        } 
    } 
}

转载于:https://www.cnblogs.com/hongwei8455/p/3658574.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值