zoukankan      html  css  js  c++  java
  • 二叉排序树——算法系列

    这个二叉树弄了一上午,不过原理上基本上懂了,还发现,其实用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);
                }
            }
        }
    }

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

  • 相关阅读:
    jchdl
    jchdl
    UVa 10256 (判断两个凸包相离) The Great Divide
    UVa 11168 (凸包+点到直线距离) Airport
    LA 2572 (求可见圆盘的数量) Kanazawa
    UVa 10652 (简单凸包) Board Wrapping
    UVa 12304 (6个二维几何问题合集) 2D Geometry 110 in 1!
    UVa 10674 (求两圆公切线) Tangents
    UVa 11796 Dog Distance
    LA 3263 (平面图的欧拉定理) That Nice Euler Circuit
  • 原文地址:https://www.cnblogs.com/7ants/p/2986379.html
Copyright © 2011-2022 走看看