二叉搜尋樹

pojianbing發表於2024-10-19
public class BinarSearchTree
{
    private Node _tree;

    public BinarSearchTree(List<int> datas)
    {
        if (datas != null)
        {
            foreach (var item in datas)
            {
                Insert(item);
            }
        }
    }

    /// <summary>
    /// 插入
    /// </summary>
    /// <param name="data"></param>
    public void Insert(int data)
    {
        if (_tree == null)
        {
            _tree = new Node(data);
        }
        else
        {
            var current = _tree;

            while (current != null)
            {
                if (data > current.Data)
                {
                    if (current.Right == null)
                    {
                        current.Right = new Node(data, current);
                        break;
                    }

                    current = current.Right;
                }
                else if (data < current.Data)
                {
                    if (current.Left == null)
                    {
                        current.Left = new Node(data, current);
                        break;
                    }

                    current = current.Left;
                }
            }
        }
    }

    /// <summary>
    /// 刪除
    /// </summary>
    /// <param name="data"></param>
    public void Delete(int data)
    {
        var node = Find(data);
        if (node == null) return;

        if (node.Left == null && node.Right == null)
        {
            if (node.Parent == null)
            {
                _tree = null;
            }
            else
            {
                // 直接刪除即可
                DeleteFromParent(node);
            }
        }
        else if (node.Left != null && node.Right != null)
        {
            if (node.Parent == null)
            {
                _tree = null;
            }
            else
            {
                // 查詢右子樹最大節點
                var minNode = node.Right;
                var currentNode = node.Right;
                while (currentNode != null)
                {
                    minNode = currentNode;
                    currentNode = minNode.Left;
                }

                DeleteFromParent(minNode);
                ReplaceChildNode(node, minNode);
            }
        }
        else
        {
            // 有一個子節點,則直接將子節點掛到父節點下
            var child = node.Left ?? node.Right;

            if (node.Parent == null)
            {
                _tree = child;
            }
            else
            {
                ReplaceChildNode(node, child);
            }
        }
    }

    private void ReplaceChildNode(Node node, Node newNode)
    {
        newNode.Parent = node.Parent;

        if (node.Parent.Left == node)
        {
            node.Parent.Left = newNode;
        }

        if (node.Parent.Right == node)
        {
            node.Parent.Right = newNode;
        }
    }

    private void DeleteFromParent(Node node)
    {
        if (node.Parent.Left == node)
        {
            node.Parent.Left = null;
        }

        if (node.Parent.Right == node)
        {
            node.Parent.Right = null;
        }
    }

    /// <summary>
    /// 查詢
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public Node Find(int data)
    {
        var current = _tree;

        while (current != null)
        {
            if (data > current.Data)
            {
                current = current.Right;
            }
            else if (data < current.Data)
            {
                current = current.Left;
            }
            else
            {
                return current;
            }
        }

        return null;
    }
}

public class Node
{
    public Node(int data, Node parent = null)
    {
        this.Data = data;
        Parent = parent;
    }

    public int Data { get; set; }
    public Node Left { get; set; }
    public Node Right { get; set; }
    public Node Parent { get; set; }
}

相關文章