二叉搜索树的C#实现

二叉搜索树又称二叉查找树,亦称为二叉排序树。性质如下:
(1)若左子树不空,则左子树上所有节点的值均小于它的根节点的值;
(2)若右子树不空,则右子树上所有节点的值均大于它的根节点的值;
(3)左、右子树也分别为二叉搜索树;
基础知识介绍
在这里插入图片描述
上图中A为B的双亲结点,B为A的孩子结点。根为第一层,根的孩子为第二层,树中结点的最大层次数称为树的深度或高度。上图所示树的深度为4。
现将一组数{61, 87, 59, 47, 35, 73, 51, 98, 37, 93}此序列构造二叉搜索树,构造过程如下:
(1)i = 0,A[0] = 61,节点61作为根节点;
(2)i = 1,A[1] = 87,87 > 61,且节点61右孩子为空,故81为61节点的右孩子;
(3)i = 2,A[2] = 59,59 < 61,且节点61左孩子为空,故59为61节点的左孩子;
(4)i = 3,A[3] = 47,47 < 59,且节点59左孩子为空,故47为59节点的左孩子;
(5)i = 4,A[4] = 35,35 < 47,且节点47左孩子为空,故35为47节点的左孩子;
(6)i = 5,A[5] = 73,73 < 87,且节点87左孩子为空,故73为87节点的左孩子;
(7)i = 6,A[6] = 51,47 < 51,且节点47右孩子为空,故51为47节点的右孩子;
(8)i = 7,A[7] = 98,98 < 87,且节点87右孩子为空,故98为87节点的右孩子;
(9)i = 8,A[8] = 93,93 < 98,且节点98左孩子为空,故93为98节点的左孩子
C#代码实现,代码来自https://www.cnblogs.com/BrokenIce/p/5929169.htm,做了修改l

 class Node
    {
        private object _data;
        private Node _left;
        private Node _right;
        public object Data
        {
            get { return _data; }
            set { _data = value; }
        }
        public Node Left
        {
            get { return _left; }
            set { _left = value; }
        }
        public Node Right
        {
            get { return _right; }
            set { _right = value; }
        }
        public Node(object data)
        {
            this._data = data;
        }
        public override string ToString()//重写
        {
            return _data.ToString();
        }
    }
 class BinaryTree
    {
        private Node _head;
        private string cStr;
        public Node Head
        {
            get { return _head; }
            set { _head = value;}
        }
        public BinaryTree()
        {
            _head=null;
        }
//**********构建二叉搜索树
        public Node rootNode = null;
        public void Insert(int data)
        {
            Node Parent;           
            //将所需插入的数据包装进节点
            Node newNode = new Node(data);           
            //如果为空树,则插入根节点
            if (rootNode == null)
            {
                rootNode = newNode;
            }
            else//否则找到合适叶子节点位置插入
            {
                Node Current = rootNode;
                while (true)
                {
                    Parent = Current;
                    if ((int)newNode.Data < (int)Current.Data)
                    {
                        Current = Current.Left;
                        if (Current == null)
                        {
                            Parent.Left = newNode;
                            //插入叶子后跳出循环
                            break;
                        }
                    }
                    else
                    {
                        Current = Current.Right;
                        if (Current == null)
                        {
                            Parent.Right = newNode;
                            //插入叶子后跳出循环
                            break;
                        }
                    }
                }
            }
         }
 //递归先序遍历
        public void PreOrder(Node node)
        {
            if (node != null)
            {
                Console.Write(node);
                Console.Write(" ");
                PreOrder(node.Left);
                PreOrder(node.Right);               
            }
        }
        //递归中序遍历
        public void InOrder(Node node)
        {
            if (node != null)
            {
                InOrder(node.Left);
                Console.Write(node);
                Console.Write(" ");
                InOrder(node.Right);
            }
        }
        //递归后序遍历
        public void AfterOrder(Node node)
        {
            if (node != null)
            {
                AfterOrder(node.Left);
                AfterOrder(node.Right);
                Console.Write(node);
                Console.Write(" ");
            }
        }
   }

class Program
    {
        static void Main(string[] args)
        {
            //*****
            BinaryTree b = new BinaryTree();
            /*插入节点*/
            b.Insert(61);
            b.Insert(87);
            b.Insert(59);
            b.Insert(47);
            b.Insert(35);
            b.Insert(73);
            b.Insert(51);
            b.Insert(98);
            b.Insert(37);
            b.Insert(93);          
            /*插入结束 */
            Console.Write("先序遍历:");
            b.PreOrder(b.rootNode);
            Console.WriteLine(" ");
            Console.Write("\n中序遍历:");
            b.InOrder(b.rootNode);
            Console.Write("\n后序遍历:");
            b.AfterOrder(b.rootNode);        
           
            Console.ReadLine();
            //*****            
        }
    }
 //找到最大节点
        public void FindMax()
        {
            Node current = rootNode;
            //找到最右边的节点即可
            while (current.Right != null)
            {
                current = current.Right;
            }
            Console.WriteLine("\n最大节点为:" + current.Data);

        }
        //找到最小节点
        public void FindMin()
        {
            Node current = rootNode;
            //找到最左边的节点即可
            while (current.Left != null)
            {
                current = current.Left;
            }
            Console.WriteLine("\n最小节点为:" + current.Data);
        }
public Node Delete(int key)//删除操作
        {
            Node parent = rootNode;
            Node current = rootNode;
            //首先找到需要被删除的节点&其父节点
            while (true)
            {
                if (key <(int) current.Data)
                {
                    if (current.Left == null)
                        break;
                    parent = current;
                    current = current.Left;
                }
                else if (key > (int)current.Data)
                {
                    if (current == null)
                        break;
                    parent = current;
                    current = current.Right;
                }
                //找到被删除节点,跳出循环
                else
                {
                    break;
                }
            }
            //找到被删除节点后,分四种情况进行处理
            //情况一,所删节点是叶子节点时,直接删除即可
            if (current.Left == null && current.Right == null)
            {
                //如果被删节点是根节点,且没有左右孩子
                if (current == rootNode && rootNode.Left == null && rootNode.Right == null)
                {
                    rootNode = null;
                }
                else if ((int)current.Data <(int) parent.Data)
                    parent.Left = null;
                else
                    parent.Right = null;
            }
            //情况二,所删节点只有左孩子节点时
            else if (current.Left != null && current.Right == null)
            {
                if ((int)current.Data < (int)parent.Data)
                    parent.Left = current.Left;
                else
                    parent.Right = current.Left;


            }
            //情况三,所删节点只有右孩子节点时
            else if (current.Left == null && current.Right != null)
            {
                if ((int)current.Data < (int)parent.Data)
                    parent.Left = current.Right;
                else
                    parent.Right = current.Right;


            }
            //情况四,所删节点有左右两个孩子
            else
            {
                //current是被删的节点,temp是被删左子树最右边的节点
                Node temp;
                //先判断是父节点的左孩子还是右孩子
                if ((int)current.Data < (int)parent.Data)
                {

                    parent.Left = current.Left;
                    temp = current.Left;
                    //寻找被删除节点最深的右孩子
                    while (temp.Right != null)
                    {
                        temp = temp.Right;
                    }
                    temp.Right = current.Right;


                }
                //右孩子
                else if ((int)current.Data > (int)parent.Data)
                {
                    parent.Right = current.Left;
                    temp = current.Left;
                    //寻找被删除节点最深的左孩子
                    while (temp.Left != null)
                    {
                        temp = temp.Left;
                    }
                    temp.Right = current.Right;
                }
                //当被删节点是根节点,并且有两个孩子时
                else
                {
                    temp = current.Left;
                    while (temp.Right != null)
                    {
                        temp = temp.Right;
                    }
                    temp.Right = rootNode.Right;
                    rootNode = current.Left;
                }

            }
            return current;

        }
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现二叉搜索树的层次遍历,您可以使用队列数据结构来帮助进行层次遍历。下面是一个使用C语言实现二叉搜索树层次遍历的示例代码: ```c#include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构struct Node { int data; struct Node* left; struct Node* right; }; // 创建新节点struct Node* createNode(int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); if (newNode == NULL) { printf("内存分配失败!"); exit(1); } newNode->data = data; newNode->left = NULL; newNode->right = NULL; return newNode; } // 插入节点到二叉搜索树struct Node* insertNode(struct Node* root, int data) { if (root == NULL) { return createNode(data); } if (data < root->data) { root->left = insertNode(root->left, data); } else if (data > root->data) { root->right = insertNode(root->right, data); } return root; } // 层次遍历二叉树void levelOrderTraversal(struct Node* root) { if (root == NULL) { return; } // 创建一个队列来辅助层次遍历 struct Node** queue = (struct Node**)malloc(sizeof(struct Node*) *100); int front =0, rear =0; // 将根节点入队 queue[rear++] = root; while (front < rear) { struct Node* current = queue[front++]; printf("%d ", current->data); // 将左右子节点入队 if (current->left != NULL) { queue[rear++] = current->left; } if (current->right != NULL) { queue[rear++] = current->right; } } //释放队列内存 free(queue); } int main() { struct Node* root = NULL; // 插入节点到二叉搜索树 root = insertNode(root,50); root = insertNode(root,30); root = insertNode(root,20); root = insertNode(root,40); root = insertNode(root,70); root = insertNode(root,60); root = insertNode(root,80); // 层次遍历二叉树 printf("层次遍历结果:"); levelOrderTraversal(root); return0; } ``` 在上述代码中,我们首先定义了一个二叉树节点结构 `struct Node`,然后使用 `createNode` 函数创建新节点,使用 `insertNode` 函数将节点插入到二叉搜索树中。 在 `levelOrderTraversal` 函数中,我们使用队列来辅助层次遍历。我们通过循环从队列中取出节点,并打印节点的值。然后将该节点的左右子节点(如果存在)入队。直到队列为空。 在 `main` 函数中,我们创建了一个二叉搜索树,并调用 `levelOrderTraversal` 函数进行层次遍历。 运行上述代码,将会输出二叉搜索树的层次遍历结果。例如,对于示例中的二叉搜索树,输出结果为:50307020406080。 希望这个示例代码对您有所帮助!如果您有任何进一步的问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值