精华内容
下载资源
问答
  • linux红黑树源码

    2012-09-02 20:43:25
    linux中的红黑树,被广泛的应用linux内核的模块中。 高质量的代码值得拥有。
  • Linux上直观显示红黑树结构,方便大家测试验证

    最近在学习Linux内核里的红黑树,发现网站上都没有一点好的实例能直观表达。参考了网上一些大神的技巧,终于在

    终端上实现直观表达红黑树。

    我们这次使用的红黑树代码是从Linux内核拷贝出来的:include/linux/rbtree.h 和 lib/rbtree.c

    由于我们的代码是应用程序上实现的,所以要对这两个文件做一些修改:

    rbtree.h:


    注:注释掉两行头文件,加入offsetof和container_of的宏定义

    rbtree.c:



    注:注释掉头文件,加入自己改过的rbtree.h,注释掉原来所有的EXPORT_SYMBOL


    接下去我们开始正式红黑树编程,这次红黑树实例是下图:


    实现的代码test.c:

    #include <stdio.h>
    #include "rbtree.h"
    #include <stdlib.h>
    #include <time.h>

    struct mytype {
    struct rb_node node;
    int key;
    };

    struct rb_root mytree = RB_ROOT;

    /** Same as binary sort tree**/
    struct mytype *my_search(struct rb_root *root, int key)
    {
    struct rb_node *node = root->rb_node;
    struct mytype *data;
    while (node) {
    data = container_of(node, struct mytype, node);
    int result;

    if(key < data->key) result = -1;
    else if(key > data->key) result = 1;
    else result = 0;

    if (result < 0)
    node = node->rb_left;
    else if (result > 0)
    node = node->rb_right;
    else
    return data;

    return NULL;
    }

    int my_insert(struct rb_root *root, struct mytype *data)
    {
    struct rb_node **new = &(root->rb_node), *parent = NULL;
            struct mytype *this;
    /* Figure out where to put new node */
    while (*new) {
    this = container_of(*new, struct mytype, node);


    int result;

    if(this->key > data->key) result = -1;
    else if(this->key  < data->key) result = 1;
    else result = 0;

    parent = *new;
    if (result < 0)
    new = &((*new)->rb_left);
    else if (result > 0)
    new = &((*new)->rb_right);
    else
    return 0;
    }

    /* Add new node and rebalance tree. */
    rb_link_node(&(data->node), parent, new);
    rb_insert_color(&(data->node), root);


    return 1;
    }
    int array[]={13,15,11,8,17,1,6,22,25,27};    //上图所示红黑树实例

    #define TAB_SIZE(array) (sizeof(array)/sizeof(array[0])) 

    void padding ( char ch, int n )
    {
    int i;
    if(n>0)
    {
    for ( i = 0; i < (n-1); i++ )
    printf ( "%c",ch );
    printf ( "--------" );
    }
    }

    void print_node ( struct rb_node *node, int level )
    {
    if ( node == NULL )
    {
    padding ( '\t', level );
    printf ( "\033[42;37m%s\033[0m\n", "null" );
    }
    else
    {
    print_node ( node->rb_right, level + 1 );
    padding ( '\t', level );
    if(rb_is_black(node))
    {
           struct mytype *black = container_of(node, struct mytype, node);
    printf ( "\033[47;30m%3d\033[0m\n", black->key );
    }
    else
    {
           struct mytype *red = container_of(node, struct mytype, node);
    printf ( "\033[41;37m%3d\033[0m\n", red->key );
    }
    print_node ( node->rb_left, level + 1 );
    }
    }

    void print_tree(struct rb_root* tree)
    {
        printf("-------------------------------------------\n");
    print_node(tree->rb_node,0);
    printf("-------------------------------------------\n");
    }
    int  main(void)
    {
    struct rb_node *node;
    struct mytype *mynode;
    int i;


    for(i = 0; i < TAB_SIZE(array); i++)
    {
    mynode = malloc(sizeof(struct mytype));
    //array[i]=(rand()%100);
    mynode->key= array[i];
    printf("i = %d, key is %d\n", i,mynode->key);
    my_insert(&mytree, mynode); 
    }


    printf("*********** Up ****************************\n");
    i = 0;
    for(node = rb_first(&mytree); node; node = rb_next(node))
    {
    printf("i = %d, key = %d\n", i, (rb_entry(node, struct mytype, node))->key);
    i++;
    }
    printf("------------Down---------------------------\n");
    i = 0;
    for(node = rb_last(&mytree); node; node = rb_prev(node))
    {
    printf("i = %d, key = %d\n", i, (rb_entry(node, struct mytype, node))->key);
    i++;
    }
            /*
    printk("------------Erase and Up---------------------------\n");
    mynode = my_search(&mytree, array[2]);
    if(mynode) 
    {
    rb_erase(&(mynode->node), &mytree);
    kfree(mynode);
    printk("Erased %d node !\n",array[2]);
    }
    */

        print_tree(&mytree);
        printf("-------------------------------------------------------\n");
    return 0;
    }
    编译:gcc -o rbtree rbtree.c test.c 

    运行结果如下图:

    非常直观表示红黑树,有助于学习和测试。

    遗留问题:

    在测试时发现,在内核当中不能用,好像递归函数在内核中使用会有问题,网上查好像是内核栈不够。

    红黑树的元素插入顺序不一样,生成的树也不一样:

    int array[]={8,25,1,13,15,11,17,6,22,27};   //上图所示红黑树实例顺序改变

    运行结果:



    希望各大神指点指点,谢谢!




    展开全文
  • 红黑树linux内核红黑树探讨

    千次阅读 多人点赞 2014-01-16 20:12:11
    红黑树相信大家有一定的了解,红黑树是一种应用很广泛的数据结构,详情点这里。 比如在linux内核,nginx等众多开源软件中有应用。发现有很多文章已经把红黑树分析的很好了,现在罗列一下,供以后学习。 红黑树的...

    红黑树相信大家有一定的了解,红黑树是一种应用很广泛的数据结构,详情点这里

    比如在linux内核,nginx等众多开源软件中有应用。

    红黑树的关键点就是 节点的插入删除。

    插入节点的关键是:
        插入新节点总是红色节点
        如果插入节点的父节点是黑色, 能维持性质
        如果插入节点的父节点是红色, 破坏了性质. 故插入算法就是通过重新着色或旋转, 来维持性质


    删除节点的关键是:
        如果删除的是红色节点, 不破坏性质
        如果删除的是黑色节点, 那么这个路径上就会少一个黑色节点, 破坏了性质. 故删除算法就是通过重新着色或旋转, 来维持性质

    通过google可以 发现有很多文章已经把红黑树分析的很好了,现在罗列一下,供以后学习。

    红黑树的介绍和实现

     红黑树算法的层层剖析与逐步实现

    红黑树

    Linux 内核红黑树的实现代码位于:

    lib/rbtree.c,同时头文件在include/linux/rbtree.h 中,内核中很多模块都使用了红黑树,详细介绍参见内核文档 Documentation/rbtree.txt。

    Linux内核中的红黑树

    详解Linux内核红黑



    展开全文
  • 红黑树特性Linux内存管理 有这么一句话:如果对查找效率要求过高,而且又需要平凡的去增删改操作时就应该想到使用红黑树!因为红黑树的特性就是:查找效率较高,增删效率也较高,自身是平衡的,没有AVL树强平衡,...

    红黑树特性Linux内存管理

    有这么一句话:如果对查找效率要求过高,而且又需要平凡的去增删改操作时就应该想到使用红黑树!因为红黑树的特性就是:查找效率较高,增删效率也较高,自身是平衡的,没有AVL树强平衡,所以它在删除操作时要比AVL树优秀很多,红黑树来源于2-3树,它的五条性质都来源于2-3树,就是高度和宽度之间的博弈,而且每条性质都顺其自然。有兴趣可以研究一下,真的很有意思哦。

    Linux内存管理模块使用红黑树来提升虚拟内存的查找速度,我们来看看Linux内核目录下的rbtree.c文件:

    插入,基本就是红黑树的插入节点调整操作

    void rb_insert_color(rb_node_t * node, rb_root_t * root)
    {
    	rb_node_t * parent, * gparent;//一个父节点一个祖父节点
    	//只有当父节点为红色的时候才需要调整
    	while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
    	{
    		gparent = parent->rb_parent;
     		//如果父节点是爷爷的左子节点,就去判断叔叔节点,是红色就变色操作,否则就进行旋转操作
    		if (parent == gparent->rb_left)
    		{
    			{
    				register rb_node_t * uncle = gparent->rb_right;
    				if (uncle && uncle->rb_color == RB_RED)
    				{
    					uncle->rb_color = RB_BLACK;
    					parent->rb_color = RB_BLACK;
    					gparent->rb_color = RB_RED;
    					node = gparent;
    					continue;
    				}
    			}
     
    			if (parent->rb_right == node)
    			{
    				register rb_node_t * tmp;
    				__rb_rotate_left(parent, root);
    				tmp = parent;
    				parent = node;
    				node = tmp;
    			}
     
    			parent->rb_color = RB_BLACK;
    			gparent->rb_color = RB_RED;
    			__rb_rotate_right(gparent, root);
    		} else {//当父节点是右子节点的时候就反过来即可
    			{
    				register rb_node_t * uncle = gparent->rb_left;
    				if (uncle && uncle->rb_color == RB_RED)
    				{
    					uncle->rb_color = RB_BLACK;
    					parent->rb_color = RB_BLACK;
    					gparent->rb_color = RB_RED;
    					node = gparent;
    					continue;
    				}
    			}
     
    			if (parent->rb_left == node)
    			{
    				register rb_node_t * tmp;
    				__rb_rotate_right(parent, root);
    				tmp = parent;
    				parent = node;
    				node = tmp;
    			}
     
    			parent->rb_color = RB_BLACK;
    			gparent->rb_color = RB_RED;
    			__rb_rotate_left(gparent, root);
    		}
    	}
     	//最后把根节点颜色改变一下,保证性质一
    	root->rb_node->rb_color = RB_BLACK;
    }
    

    删除操作有兴趣的可以去我的github上看一下https://github.com/yc299792/C-/blob/master/算法类%2FTree%2Frbtreeerase.md:

    void rb_erase(rb_node_t * node, rb_root_t * root)
    {
    	rb_node_t * child, * parent;
    	int color;
     
    	if (!node->rb_left)
    		child = node->rb_right;
    	else if (!node->rb_right)
    		child = node->rb_left;
    	else
    	{
    		rb_node_t * old = node, * left;
     
    		node = node->rb_right;
    		while ((left = node->rb_left))
    			node = left;
    		child = node->rb_right;
    		parent = node->rb_parent;
    		color = node->rb_color;
     
    		if (child)
    			child->rb_parent = parent;
    		if (parent)
    		{
    			if (parent->rb_left == node)
    				parent->rb_left = child;
    			else
    				parent->rb_right = child;
    		}
    		else
    			root->rb_node = child;
     
    		if (node->rb_parent == old)
    			parent = node;
    		node->rb_parent = old->rb_parent;
    		node->rb_color = old->rb_color;
    		node->rb_right = old->rb_right;
    		node->rb_left = old->rb_left;
     
    		if (old->rb_parent)
    		{
    			if (old->rb_parent->rb_left == old)
    				old->rb_parent->rb_left = node;
    			else
    				old->rb_parent->rb_right = node;
    		} else
    			root->rb_node = node;
     
    		old->rb_left->rb_parent = node;
    		if (old->rb_right)
    			old->rb_right->rb_parent = node;
    		goto color;
    	}
     
    	parent = node->rb_parent;
    	color = node->rb_color;
     
    	if (child)
    		child->rb_parent = parent;
    	if (parent)
    	{
    		if (parent->rb_left == node)
    			parent->rb_left = child;
    		else
    			parent->rb_right = child;
    	}
    	else
    		root->rb_node = child;
     
     color:
    	if (color == RB_BLACK)
    		__rb_erase_color(child, parent, root);
    }
    

    调整操作:

    static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
    			     rb_root_t * root)
    {
    	rb_node_t * other;
     
    	while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
    	{
    		if (parent->rb_left == node)
    		{
    			other = parent->rb_right;
    			if (other->rb_color == RB_RED)
    			{
    				other->rb_color = RB_BLACK;
    				parent->rb_color = RB_RED;
    				__rb_rotate_left(parent, root);
    				other = parent->rb_right;
    			}
    			if ((!other->rb_left ||
    			     other->rb_left->rb_color == RB_BLACK)
    			    && (!other->rb_right ||
    				other->rb_right->rb_color == RB_BLACK))
    			{
    				other->rb_color = RB_RED;
    				node = parent;
    				parent = node->rb_parent;
    			}
    			else
    			{
    				if (!other->rb_right ||
    				    other->rb_right->rb_color == RB_BLACK)
    				{
    					register rb_node_t * o_left;
    					if ((o_left = other->rb_left))
    						o_left->rb_color = RB_BLACK;
    					other->rb_color = RB_RED;
    					__rb_rotate_right(other, root);
    					other = parent->rb_right;
    				}
    				other->rb_color = parent->rb_color;
    				parent->rb_color = RB_BLACK;
    				if (other->rb_right)
    					other->rb_right->rb_color = RB_BLACK;
    				__rb_rotate_left(parent, root);
    				node = root->rb_node;
    				break;
    			}
    		}
    		else
    		{
    			other = parent->rb_left;
    			if (other->rb_color == RB_RED)
    			{
    				other->rb_color = RB_BLACK;
    				parent->rb_color = RB_RED;
    				__rb_rotate_right(parent, root);
    				other = parent->rb_left;
    			}
    			if ((!other->rb_left ||
    			     other->rb_left->rb_color == RB_BLACK)
    			    && (!other->rb_right ||
    				other->rb_right->rb_color == RB_BLACK))
    			{
    				other->rb_color = RB_RED;
    				node = parent;
    				parent = node->rb_parent;
    			}
    			else
    			{
    				if (!other->rb_left ||
    				    other->rb_left->rb_color == RB_BLACK)
    				{
    					register rb_node_t * o_right;
    					if ((o_right = other->rb_right))
    						o_right->rb_color = RB_BLACK;
    					other->rb_color = RB_RED;
    					__rb_rotate_left(other, root);
    					other = parent->rb_left;
    				}
    				other->rb_color = parent->rb_color;
    				parent->rb_color = RB_BLACK;
    				if (other->rb_left)
    					other->rb_left->rb_color = RB_BLACK;
    				__rb_rotate_right(parent, root);
    				node = root->rb_node;
    				break;
    			}
    		}
    	}
    	if (node)
    		node->rb_color = RB_BLACK;
    }
    
    展开全文
  • 90分钟了解4种红黑树Linux内核应用场景 1.进程管理与调度的红黑树 2.虚拟内存区域的红黑树 3.网络sk_buff的红黑树 4.epoll的红黑树Linux内核系列】花90分钟了解4种红黑树Linux内核应用场景丨epoll的红黑树...

    90分钟了解 4种红黑树的Linux内核应用场景


    1. 进程管理与调度的红黑树
    2. 虚拟内存区域的红黑树
    3. 网络sk_buff的红黑树 
    4. epoll的红黑树

    【Linux内核系列】花90分钟了解4种红黑树的Linux内核应用场景丨epoll的红黑树讲解

    C/C++Linux服务器开发精彩内容包括:C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,P2P,Linux内核,Docker,TCP/IP,协程,DPDK多个高级知识点分享。点击链接订阅后直接观看:C/C++Linux服务器开发/Linux后台架构师-学习视频

    Linux服务器开发高级架构qun:720209036。   更多Linux服务器开发精彩内容关注VX公众号:Linux服务器

    展开全文
  • 对比 paho.mqtt.c / nginx / libuv / linux红黑树的实现发现,Linux 内核中红黑树的实现部分最为经典,本文通过对 Linux 内核中红黑树的实现进行初步分析,并利用 Linux 内核中红黑树的接口,引用《算法导论》中...
  • 红黑树linux中的3种应用场景,听完终身难忘 1.虚拟内存管理 2.进程管理调度器实现 3.网络协议栈的红黑树Linux后台开发系列】红黑树linux中的3种应用场景,听完受益匪浅 更多精彩内容包括:C/C++,Linux,...
  • 一、B应用1、B大量应用在数据库和文件系统当中。它的设计思想是,将相关数据尽量集中在一起,以便一次读取多个数据,减少硬盘操作次数。B算法减少定位记录时所经历的中间过程,从而加快存取速度。假定一个...
  • 红黑树是非常重要的一个概念,对于技术的理解有必要非常精准地表达出来,二不是非常模糊地用可能这样的词汇。普遍的工程师,能够使用技术词汇,但是不能精准地使用它们。 红黑树的性能 每个节点是红色的或者黑色的 ...
  • 红黑树应用 (1).mp4

    2020-09-05 14:36:09
    内容包括:C/C++,Linux,Nginx,golang,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,ffmpeg,流媒体, 音视频,CDN,P2P,K8S,Docker,Golang,TCP/IP,协程,嵌入式,ARM,DPDK等等。。。
  • 红黑树linux中的3种应用场景,听完受益匪浅 5种红黑树的场景,从Linux内核谈到Nginx源码,听完醍醐灌顶 c/c++Linux后台服务器开发高级架构师视频资料 二叉搜索树 二叉搜索树又叫二叉查找树、二叉排序树,我们...
  • linux内核红黑树运用小实例

    千次阅读 2016-12-01 11:11:34
    linux内核版本linux-3.10.36 结构 linux内核的rb_node结构体 struct rb_node { unsigned long __rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } __attribute__((aligned(sizeof...
  • C++ STL中的map就是用红黑树实现的。AVL树和红黑树都是二叉搜索树的变体,他们都是用于搜索。因为在这些书上搜索的时间复杂度都是O(h),h为树高,而理想状况是h为n。所以构造的办法就是把二叉搜...
  • Linux内核的红黑树源码实现以及调用

    千次阅读 多人点赞 2019-04-28 19:33:02
    红黑树可以说是程序员经常遇到的一种数据结构,不管是工作还是面试都会涉及,有时候还会让你写一段红黑树代码。 本文主要是讲Linux中的红黑树,关于红黑树定义参考wiki:...Linux中的红黑树(rbtree) 下面...
  • linux内核之红黑树

    2014-02-28 15:37:20
    linux内核经常使用红黑树来提高普通链表的遍历效率,因此,算法学的不好的人,至少得认真学会红黑树,才能了解内核是怎么提高遍历性能的,才能理解很多优化的算法。 转   推荐阅读:Left-Leaning Red-Black ...
  • B树,B+树,红黑树应用场景笔记

    万次阅读 多人点赞 2018-07-18 13:01:51
    一、B应用 1、B大量应用在数据库和文件系统当中。 它的设计思想是,将相关数据尽量集中在一起,以便一次读取多个数据,减少硬盘操作次数。B算法减少定位记录时所经历的中间过程,从而加快存取速度。 假定...
  • 前言:R-B Tree,又称为“红黑树”。本文参考了《算法导论...大牛教你学Linux内核红黑树应用 面试必备技能,Linux内核中的3种使用 红黑树在linux中的3种应用场景,听完终身难忘 二、红黑树(R-B Tree)简介 R-B Tree,.
  • 红黑树应用开发及性能测试

    千次阅读 2017-04-06 16:45:10
    1、概述 本文主要描述红黑树的概念、经典应用场景,并在应用开发层面示例代码说明红黑树的高效特性。 2、epoll 与红黑树 epoll 的高效就在于,当我们调用 epoll_ctl 保存上百万个句柄,epoll_wait 仍然可以飞快的...
  • linux红黑树使用实例

    千次阅读 2016-01-19 23:17:45
    最近使用到红黑树写了一个电话本,使用的linux内核中的标准接口,然后加上了一些自己写的接口和测试程序,记录如下,方便后续使用,以下代码网上几乎都可以找到,只是根据自己所做的项目做了一点修正: rbtree.h /...
  • linux中的红黑树

    2010-11-09 11:02:00
    Linux内核在管理vm_area_struct时就是采用了红黑树来维护内存块的。先到include/linux/rbtree.h中看一下红黑树的一些定义,如下:struct rb_node{ unsigned long rb_parent_color;#define RB_RED 
  • 大牛教你学Linux内核红黑树应用 面试必备技能,Linux内核中的3种使用 红黑树在linux中的3种应用场景,听完终身难忘 二、红黑树的介绍 红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含...
  •  内核源码:linux-2.6.38.8.tar.bz2    关于二叉查找的概念请参考博文《详解二叉查找算法的实现》。  平衡二叉树(BalancedBinary Tree或Height-Balanced Tree)又称AVL。它或者是一棵空,或者是具有...
  • Linux内核中的红黑树

    千次阅读 2012-10-20 00:49:15
    红黑树是平衡二叉树的一种,它有很好的性质,树中的...Linux内核在管理vm_area_struct时就是采用了红黑树来维护内存块的。 先到include/linux/rbtree.h中看一下红黑树的一些定义,如下: struct rb_node
  • 红黑树

    2016-10-28 13:30:22
    但是在实际应用红黑树应用最多,比如C++STL库--map/set,java库,Linux内核以及其他的一些库里都用到了红黑树,这是因为红黑树是不追求完全平衡的是一种近似平衡的二叉树,保证最长路径不超过最短路径的二倍,相...
  • 红黑树 1.概述 红黑树是一颗二叉搜索树,它在每个节点上增加了一个存储位表示节点的颜色,可以是RED或BLACK。通过对任何一条从根到叶子的简单路径上各个节点的颜色进行约束,红黑树确保没有路径会比其他路径长出2倍...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,505
精华内容 5,402
关键字:

linux红黑树应用

linux 订阅