• 二叉排序树——算法系列


    这个二叉树弄了一上午,不过原理上基本上懂了,还发现,其实用C来写树的话,由于指针的存在更容易理解。

    下面是代码,参考“一线码农”,发现他的删除函数其实写的是有问题的,经过修改之后顺利通过。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    //哈希查找程序
    namespace Test
    {
        class Program
        {
            
            static void Main(string[] args)
            {
                List<int> list = new List<int>() { 50, 30, 70, 10, 40, 90, 80 };
                //创建二叉树
                BSTree bsTree = CreateBST(list);
                Console.Write("中序遍历的原始数据:");
                LDR_BST(bsTree);
                Console.WriteLine("\n--------------------------------------");
                Console.WriteLine("\n10在二叉树中是否包含:" + SearchBST(bsTree, 10));
                Console.WriteLine("\n--------------------------------------");
                bool isExcute = false;
                InsertBST(bsTree, 20, ref isExcute);
                Console.WriteLine("\n20插入到二叉树,中序遍历为:");
                LDR_BST(bsTree);
                Console.WriteLine("\n--------------------------------------");
                Console.WriteLine("删除叶子节点20,\n中序遍历:");
                DeleteBST(ref bsTree, 20);
                LDR_BST(bsTree);
                Console.WriteLine("\n--------------------------------------");
                Console.WriteLine("删除单孩子节点90,\n中序遍历:");
                DeleteBST(ref bsTree, 90);
                LDR_BST(bsTree);
                Console.WriteLine("\n--------------------------------------");
                Console.WriteLine("删除根节点50,\n中序遍历:");
                DeleteBST(ref bsTree, 50);
                LDR_BST(bsTree);
                Console.ReadLine();
            }
            //二叉排序树结构
            public class BSTree
            {
                public int data;
                public BSTree left;
                public BSTree right;
            }
    
            static void InsertBST(BSTree bsTree, int key, ref bool isExcute)
            {
                if (bsTree == null)
                    return;
                if (bsTree.data > key)
                    InsertBST(bsTree.left, key, ref isExcute);
                else
                    InsertBST(bsTree.right, key, ref isExcute);
    
                if (!isExcute)
                {
                    BSTree current = new BSTree()
                    {
                        data = key,
                        left = null,
                        right = null
                    };
    
                    if (bsTree.data > key)
                        bsTree.left = current;
                    else
                        bsTree.right = current;
    
                    isExcute = true;
                }
            }
    
            static BSTree CreateBST(List<int> list)
            {
                BSTree bsTree = new BSTree()
                {
                    data = list[0],
                    left = null,
                    right = null
                };
    
                for (int i = 1; i < list.Count; i++)
                {
                    bool isExcute = false;
                    InsertBST(bsTree, list[i], ref isExcute);
                }
                return bsTree;
            }
    
            static bool SearchBST(BSTree bsTree, int key)
            {
                if (bsTree == null)
                    return false;
                if (bsTree.data == key)
                    return true;
                if (bsTree.data > key)
                    return SearchBST(bsTree.left, key);
                else
                    return SearchBST(bsTree.right, key);
            }
    
            //中序遍历二叉树
            static void LDR_BST(BSTree bsTree)
            {
                if (bsTree != null)
                {
                    LDR_BST(bsTree.left);
                    Console.Write(bsTree.data+",");
                    LDR_BST(bsTree.right);
                }
            }
    
            static void DeleteBST(ref BSTree bsTree, int key)
            {
                if (bsTree == null)
                    return;
    
                if (bsTree.data == key)
                {
                    //第一种情况:叶子节点
                    if (bsTree.left == null && bsTree.right == null)
                    {
                        bsTree = null;
                        return;
                    }
                    //第二种情况:左子树不为空
                    if (bsTree.left != null && bsTree.right == null)
                    {
                        bsTree = bsTree.left;
                        return;
                    }
                    //第三种情况,右子树不为空
                    if (bsTree.left == null && bsTree.right != null)
                    {
                        bsTree = bsTree.right;
                        return;
                    }
                    //第四种情况,左右子树都不为空
                    if (bsTree.left != null && bsTree.right != null)
                    {
                        var node = bsTree.right;//被删除节点的右孩子
                        BSTree lastPnode = bsTree;//用来保存右孩子的最左节点的父节点。
                        //找到右子树中的最左节点
                        while (node.left != null)
                        {
                            lastPnode = node;//保存左子树的父节点
                            //遍历它的左子树
                            node = node.left;
                        }
                        bsTree.data = node.data;
    
                        if (lastPnode.right == node)//删除节点的右节点没有左节点的时候。即上边的while循环没执行。
                        {
                            bsTree.right = node.right;
                        }
                        else
                        {
                            if (lastPnode.left == node)//删除节点的右节点有左节点的时候。
                            {
                                lastPnode.left = node.right;
                            }
                        }
                        node = null;//将换位到删除节点去的右子树的最左子树赋值为空。
                    }
                }
    
                if (bsTree.data > key)
                {
                    DeleteBST(ref bsTree.left, key);
                }
                else
                {
                    DeleteBST(ref bsTree.right, key);
                }
            }
        }
    }

    学完了这个,那么排序和查找也就告一段落了。

  • 相关阅读:
    Prim+堆优化
    Tarjan缩点+建新图
    CF482A
    CF545C
    CF570B
    Python 入门2 list介绍
    Python 入门1 上传代码
    黑客与画家 第十三章
    黑客与画家 第十一章
    黑客与画家 第五章
  • 原文地址:https://www.cnblogs.com/7ants/p/2986379.html
Copyright © 2020-2023  润新知