【愚公系列】2021年11月 C#版 数据结构与算法解析(红黑树)

简介: 【愚公系列】2021年11月 C#版 数据结构与算法解析(红黑树)

红黑树定义:它或者是一颗空树,或者是具有一下性质的二叉查找树


1):每个节点或是红的,或是黑的。


2):根节点是黑的。


3):每个叶节点(NIL)是黑的。(所有NULL结点称为叶子节点,且认为颜色为黑)


4):如果一个节点是红的,则他的两个子节点是黑的。


5):对每个节点,从该节点到其子孙节点的所有路径上包含相同数目的黑节点。

image.png

红黑树用在关联数组、字典的实现上。需du要的空间zhi比散列表小。 任何键值对应,需要dao随机存储和键有序的情况都可以用。

class TreeNode<T>
    {
        public T Data { get; set; }
        public TreeNode<T> LeftChild { get; set; }
        public TreeNode<T> RightChild { get; set; }
        public TreeNode<T> Parent { get; set; }
        public int Color { get; set; }
        public TreeNode(T data)
        {
            Data = data;
            Parent = null;
            LeftChild = null;
            RightChild = null;
        }
        public TreeNode(T newData, TreeNode<T> parent)
        {
            Data = newData;
            Parent = parent;
            LeftChild = null;
            RightChild = null;
        }
    }
    internal class RedBlackTree<T> where T : IComparable<T>, IEquatable<T>, new()
    {
        public TreeNode<T> Root { get; private set; }
        public int Size { get; private set; }
        public RedBlackTree()
        {
            Root = null;
            Size = 0;
        }
        private static TreeNode<T> Add(TreeNode<T> to, TreeNode<T> newNode)
        {
            if (newNode.Data.CompareTo(to.Data) < 0)
            {
                if (to.LeftChild != null) return Add(to.LeftChild, newNode);
                newNode.LeftChild = null;
                newNode.RightChild = null;
                to.LeftChild = newNode;
                newNode.Color = 1;
                newNode.Parent = to;
                return newNode;
            }
            if (to.RightChild != null) return Add(to.RightChild, newNode);
            newNode.LeftChild = null;
            newNode.RightChild = null;
            to.RightChild = newNode;
            newNode.Color = 1;
            newNode.Parent = to;
            return newNode;
        }
        private void LeftTurn(TreeNode<T> node)
        {
            if (node.RightChild == null) return;
            var child = node.RightChild;
            node.RightChild = child.LeftChild;
            if (child.LeftChild != null) child.LeftChild.Parent = node;
            child.Parent = node.Parent;
            if (node.Parent == null) Root = child;
            else
            {
                if (node == node.Parent.LeftChild)
                    node.Parent.LeftChild = child;
                else
                    node.Parent.RightChild = child;
            }
            child.LeftChild = node;
            node.Parent = child;
        }
        private void RightTurn(TreeNode<T> node)
        {
            if (node.LeftChild == null) return;
            var child = node.LeftChild;
            node.LeftChild = child.RightChild;
            if (child.RightChild != null) child.RightChild.Parent = node;
            child.Parent = node.Parent;
            if (node.Parent == null) Root = child;
            else
            {
                if (node == node.Parent.RightChild) node.Parent.RightChild = child;
                else node.Parent.LeftChild = child;
            }
            child.RightChild = node;
            node.Parent = child;
        }
        public void Insert(TreeNode<T> node)
        {
            if (Root == null)
            {
                Root = node;
                Root.Color = 0;
                Root.LeftChild = null;
                Root.RightChild = null;
                Root.Parent = null;
            }
            else
            {
                var addedNode = Add(Root, node);
                while (addedNode != Root && addedNode.Parent.Color == 1)
                {
                    if (addedNode.Parent == addedNode.Parent.Parent.LeftChild)
                    {
                        var y = addedNode.Parent.Parent.RightChild;
                        if (y != null && y.Color == 1)
                        {
                            addedNode.Parent.Color = 0;
                            y.Color = 0;
                            addedNode.Parent.Parent.Color = 1;
                            addedNode = addedNode.Parent.Parent;
                        }
                        else
                        {
                            if (addedNode == addedNode.Parent.RightChild)
                            {
                                addedNode = addedNode.Parent;
                                LeftTurn(addedNode);
                            }
                            addedNode.Parent.Color = 0;
                            addedNode.Parent.Parent.Color = 1;
                            RightTurn(addedNode.Parent.Parent);
                        }
                    }
                    else
                    {
                        var y = addedNode.Parent.Parent.LeftChild;
                        if (y != null && y.Color == 1)
                        {
                            addedNode.Parent.Color = 0;
                            y.Color = 0;
                            addedNode.Parent.Parent.Color = 1;
                            addedNode = addedNode.Parent.Parent;
                        }
                        else
                        {
                            if (addedNode == addedNode.Parent.Parent.LeftChild)
                            {
                                addedNode = addedNode.Parent;
                                RightTurn(addedNode);
                            }
                            addedNode.Parent.Color = 0;
                            addedNode.Parent.Parent.Color = 1;
                            LeftTurn(addedNode.Parent.Parent);
                        }
                    }
                }
            }
            Root.Color = 0;
        }
        private static TreeNode<T> Min(TreeNode<T> node)
        {
            while (node.LeftChild != null) node = node.LeftChild;
            return node;
        }
        private static TreeNode<T> Next(TreeNode<T> node)
        {
            if (node.RightChild != null) return Min(node.RightChild);
            var y = node.Parent;
            while (y != null && node == y.RightChild)
            {
                node = y;
                y = y.Parent;
            }
            return y;
        }
        private void FixUp(TreeNode<T> node)
        {
            while (node != Root && node.Color == 0)
            {
                if (node == node.Parent.LeftChild)
                {
                    var w = node.Parent.RightChild;
                    if (w.Color == 1)
                    {
                        w.Color = 0;
                        node.Parent.Color = 1;
                        LeftTurn(node.Parent);
                        w = node.Parent.RightChild;
                    }
                    if (w.LeftChild.Color == 0 && w.RightChild.Color == 0)
                    {
                        w.Color = 1;
                        node = node.Parent;
                    }
                    else
                    {
                        if (w.RightChild.Color == 0)
                        {
                            w.LeftChild.Color = 0;
                            w.Color = 1;
                            RightTurn(w);
                            w = node.Parent.RightChild;
                        }
                        w.Color = node.Parent.Color;
                        node.Parent.Color = 0;
                        w.RightChild.Color = 0;
                        LeftTurn(node.Parent);
                        node = Root;
                    }
                }
                else
                {
                    var w = node.Parent.LeftChild;
                    if (w.Color == 1)
                    {
                        w.Color = 0;
                        node.Parent.Color = 1;
                        RightTurn(node.Parent);
                        w = node.Parent.LeftChild;
                    }
                    if (w.RightChild.Color == 0 && w.LeftChild.Color == 0)
                    {
                        w.Color = 1;
                        node = node.Parent;
                    }
                    else
                    {
                        if (w.LeftChild.Color == 0)
                        {
                            w.RightChild.Color = 0;
                            w.Color = 1;
                            LeftTurn(w);
                            w = node.Parent.LeftChild;
                        }
                        w.Color = node.Parent.Color;
                        node.Parent.Color = 0;
                        w.LeftChild.Color = 0;
                        RightTurn(node.Parent);
                        node = Root;
                    }
                }
            }
            node.Color = 0;
        }
        public void Delete(TreeNode<T> node)
        {
            TreeNode<T> y;
            if (node.LeftChild == null || node.RightChild == null)
                y = node;
            else
                y = Next(node);
            var x = y.LeftChild ?? y.RightChild;
            if (x == null)
            {
                node.Data = y.Data;
                if (y.Parent == null) return;
                if (y.Parent.LeftChild == y) y.Parent.LeftChild = null;
                else y.Parent.RightChild = null;
                return;
            }
            x.Parent = y.Parent;
            if (y.Parent == null) Root = x;
            else
            {
                if (y == y.Parent.LeftChild) y.Parent.LeftChild = x;
                else y.Parent.RightChild = x;
            }
            if (y != node)
            {
                node.Data = y.Data;
            }
            if (y.Color == 0) FixUp(x);
        }
        private static TreeNode<T> SearchInSubTree(TreeNode<T> topNode, T data)
        {
            if (data.Equals(topNode.Data))
                return topNode;
            if (data.CompareTo(topNode.Data) < 0 && topNode.LeftChild != null)
                return SearchInSubTree(topNode.LeftChild, data);
            if (data.CompareTo(topNode.Data) > 0 && topNode.RightChild != null)
                return SearchInSubTree(topNode.RightChild, data);
            return null;
        }
        public bool Search(T data)
        {
            return SearchInSubTree(Root, data) != null;
        }
        public TreeNode<T> SearchNode(T data)
        {
            return SearchInSubTree(Root, data);
        }
        public IEnumerator<T> GetEnumerator()
        {
            if (Root == null)
                yield break;
            var current = Min(Root);
            yield return current.Data;
            while (Next(current) != null)
            {
                current = Next(current);
                yield return current.Data;
            }
        }
        public IEnumerator<TreeNode<T>> DfsEnum()
        {
            var verts = new Stack<TreeNode<T>>();
            if (Root == null)
                yield break;
            verts.Push(Root);
            var previous = 0;
            while (verts.Count != 0)
            {
                var current = verts.Peek();
                if (current.LeftChild == null && current.RightChild == null)
                {
                    verts.Pop();
                    yield return current;
                    if (current.Parent != null)
                        previous = current == current.Parent.LeftChild ? 1 : 2;
                    else
                        yield break;
                    continue;
                }
                switch (previous)
                {
                    case 0:
                        if (current.LeftChild == null)
                        {
                            previous = 1;
                            continue;
                        }
                        verts.Push(current.LeftChild);
                        previous = 0;
                        break;
                    case 1:
                        if (current.RightChild == null)
                        {
                            verts.Pop();
                            yield return current;
                            if (current.Parent != null)
                            {
                                previous = current == current.Parent.LeftChild ? 1 : 2;
                                continue;
                            }
                            yield break;
                        }
                        verts.Push(current.RightChild);
                        previous = 0;
                        break;
                    case 2:
                        verts.Pop();
                        yield return current;
                        if (current.Parent != null)
                            previous = current == current.Parent.LeftChild ? 1 : 2;
                        else
                            yield break;
                        break;
                }
            }
        }
        public IEnumerator<TreeNode<T>> BfsEnum()
        {
            var verts = new Queue<TreeNode<T>>();
            verts.Enqueue(Root);
            while (verts.Count != 0)
            {
                var current = verts.Dequeue();
                yield return current;
                if (current.LeftChild != null)
                    verts.Enqueue(current.LeftChild);
                if (current.RightChild != null)
                    verts.Enqueue(current.RightChild);
            }
        }
    }

image.png

image.png


相关文章
|
3月前
|
存储 运维 监控
基于 C# 语言的 Dijkstra 算法在局域网内监控软件件中的优化与实现研究
本文针对局域网监控系统中传统Dijkstra算法的性能瓶颈,提出了一种基于优先队列和邻接表优化的改进方案。通过重构数据结构与计算流程,将时间复杂度从O(V²)降至O((V+E)logV),显著提升大规模网络环境下的计算效率与资源利用率。实验表明,优化后算法在包含1000节点、5000链路的网络中,计算时间缩短37.2%,内存占用减少21.5%。该算法适用于网络拓扑发现、异常流量检测、故障定位及负载均衡优化等场景,为智能化局域网监控提供了有效支持。
82 5
|
4月前
|
存储 算法 安全
如何控制上网行为——基于 C# 实现布隆过滤器算法的上网行为管控策略研究与实践解析
在数字化办公生态系统中,企业对员工网络行为的精细化管理已成为保障网络安全、提升组织效能的核心命题。如何在有效防范恶意网站访问、数据泄露风险的同时,避免过度管控对正常业务运作的负面影响,构成了企业网络安全领域的重要研究方向。在此背景下,数据结构与算法作为底层技术支撑,其重要性愈发凸显。本文将以布隆过滤器算法为研究对象,基于 C# 编程语言开展理论分析与工程实践,系统探讨该算法在企业上网行为管理中的应用范式。
132 8
|
4月前
|
存储 监控 算法
解析公司屏幕监控软件中 C# 字典算法的数据管理效能与优化策略
数字化办公的时代背景下,企业为维护信息安全并提升管理效能,公司屏幕监控软件的应用日益普及。此软件犹如企业网络的 “数字卫士”,持续记录员工电脑屏幕的操作动态。然而,伴随数据量的持续增长,如何高效管理这些监控数据成为关键议题。C# 中的字典(Dictionary)数据结构,以其独特的键值对存储模式和高效的操作性能,为公司屏幕监控软件的数据管理提供了有力支持。下文将深入探究其原理与应用。
89 4
|
5月前
|
机器学习/深度学习 监控 算法
员工上网行为监控软件中基于滑动窗口的C#流量统计算法解析​
在数字化办公环境中,员工上网行为监控软件需要高效处理海量网络请求数据,同时实时识别异常行为(如高频访问非工作网站)。传统的时间序列统计方法因计算复杂度过高,难以满足低延迟需求。本文将介绍一种基于滑动窗口的C#统计算法,通过动态时间窗口管理,实现高效的行为模式分析与流量计数。
128 2
|
2月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
63 1
|
3月前
|
监控 算法 数据处理
内网实时监控中的 C# 算法探索:环形缓冲区在实时数据处理中的关键作用
本文探讨了环形缓冲区在内网实时监控中的应用,结合C#实现方案,分析其原理与优势。作为固定长度的循环队列,环形缓冲区通过FIFO机制高效处理高速数据流,具备O(1)时间复杂度的读写操作,降低延迟与内存开销。文章从设计逻辑、代码示例到实际适配效果展开讨论,并展望其与AI结合的潜力,为开发者提供参考。
177 2
|
3月前
|
监控 算法 安全
公司电脑监控软件关键技术探析:C# 环形缓冲区算法的理论与实践
环形缓冲区(Ring Buffer)是企业信息安全管理中电脑监控系统设计的核心数据结构,适用于高并发、高速率与短时有效的多源异构数据处理场景。其通过固定大小的连续内存空间实现闭环存储,具备内存优化、操作高效、数据时效管理和并发支持等优势。文章以C#语言为例,展示了线程安全的环形缓冲区实现,并结合URL访问记录监控应用场景,分析了其在流量削峰、关键数据保护和高性能处理中的适配性。该结构在日志捕获和事件缓冲中表现出色,对提升监控系统效能具有重要价值。
94 1
|
4月前
|
存储 监控 算法
基于 C# 的局域网计算机监控系统文件变更实时监测算法设计与实现研究
本文介绍了一种基于C#语言的局域网文件变更监控算法,通过事件驱动与批处理机制结合,实现高效、低负载的文件系统实时监控。核心内容涵盖监控机制选择(如事件触发机制)、数据结构设计(如监控文件列表、事件队列)及批处理优化策略。文章详细解析了C#实现的核心代码,并提出性能优化与可靠性保障措施,包括批量处理、事件过滤和异步处理等技术。最后,探讨了该算法在企业数据安全监控、文件同步备份等场景的应用潜力,以及未来向智能化扩展的方向,如文件内容分析、智能告警机制和分布式监控架构。
120 3
|
4月前
|
存储 监控 算法
内网监控桌面与 PHP 哈希算法:从数据追踪到行为审计的技术解析
本文探讨了内网监控桌面系统的技术需求与数据结构选型,重点分析了哈希算法在企业内网安全管理中的应用。通过PHP语言实现的SHA-256算法,可有效支持软件准入控制、数据传输审计及操作日志存证等功能。文章还介绍了性能优化策略(如分块哈希计算和并行处理)与安全增强措施(如盐值强化和动态更新),并展望了哈希算法在图像处理、网络流量分析等领域的扩展应用。最终强调了构建完整内网安全闭环的重要性,为企业数字资产保护提供技术支撑。
126 2
|
4月前
|
存储 监控 算法
局域网上网记录监控的 C# 基数树算法高效检索方案研究
在企业网络管理与信息安全领域,局域网上网记录监控是维护网络安全、规范网络行为的关键举措。随着企业网络数据量呈指数级增长,如何高效存储和检索上网记录数据成为亟待解决的核心问题。基数树(Trie 树)作为一种独特的数据结构,凭借其在字符串处理方面的卓越性能,为局域网上网记录监控提供了创新的解决方案。本文将深入剖析基数树算法的原理,并通过 C# 语言实现的代码示例,阐述其在局域网上网记录监控场景中的具体应用。
121 7

热门文章

最新文章

推荐镜像

更多
  • DNS