红黑树

时间限制:3000 ms  |  内存限制:65535 KB
难度:3
描写叙述

什么是红黑树呢?顾名思义,跟枣树类似。红黑树是一种叶子是黑色果子是红色的树。

。。

当然,这个是我说的。

。。

《算法导论》上可不是这么说的:

假设一个二叉查找树满足以下的红黑性质,那么则为一个红黑树。

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

2)每一个叶子节点(NIL)是黑色的

3)假设一个节点是红色的,那么他的两个儿子都是黑的。

4)根节点是黑色的。

5)对于每一个节点,从该节点到子孙节点的全部路径上包括同样数目的黑色节点。

我们在整个过程中会用到这些性质。当然,为了公平起见,事实上即使你不知道这些性质,这个题目也是能够完毕的(为什么不早说。。。。)。在红黑树的各种操作中,其核心操作被称为旋转,那么什么是旋转呢,我们来看一个样例:

如果我们这里截取红黑树的一部分,放在左边。通过操作如果能够把他转化为右边的形式,那么我们就称将根为x的子树进行了左旋,反之我们称将根为Y的树进行了右旋:

恰好慢板同学把自己红黑树弄乱了,然后请你帮忙进行修复,他将向你描写叙述他的红黑树(混乱的。

。。)。

然后告诉他须要用哪种方式旋转某个节点。在你完毕工作之后,直接向大黄提交新的树的中序遍历结果就好了。

Hint:

在这里好心的慢板同学给你简单的解释下例子:

最開始的时候树的样子是这种:

0

/    \

1       2

然后对于标号为0的节点进行右旋。结果将变为:

1

\

0

\

2

然后呢。

。。

中序遍历?这个是什么东西,哪个人能够告诉我下。

。。

输入
输入分两部分:

第一部分:一个整数T(1<=T<=10),表示測试的组数。

第二部分:第一行是一个数字N,表示红黑树的节点个数。0<N<10

然后以下有N行,每行三个数字,每一个数字的大小都在-1~N-1之间。第一个数字表示当前节点的标号,后面两个数字表示这个节点的左孩子和右孩子。假设是-1的话表示是空节点。对于全部的输入来说标号为0节点为根。

然后是一个数字M表示须要旋转的次数。M<100

接下来M行,每行有两个数字,分别表示你要旋转的节点标号和你须要的操作。标号的范围为0~n-1,假设标号后面的数字0,那么表示为左旋。假设是1,则表示右旋。

输出
每组測试返回N行数字。表示对树的中序遍历。

在每组測试数据之后留一行空行。

例子输入
1
3
0 1 2
1 -1 -1
2 -1 -1
1
0 1
例子输出
1
0
2
来源
郑州大学校赛题目

旋转加遍历

#include <stdio.h>
struct Node{
int left, right;
} tree[12]; //第11个节点作为保存树根信息的节点
int t, n, m; int findFather(int num){
for(int i = 0; i < n; ++i){
if(tree[i].left == num || tree[i].right == num)
return i;
}
return 11;
} void rotateTree(int pos, int num){
int temp = findFather(pos);;
if(num == 0){ //向左旋转
if(tree[pos].right == -1) return; if(tree[temp].left == pos)
tree[temp].left = tree[pos].right;
else tree[temp].right = tree[pos].right; temp = tree[tree[pos].right].left;
tree[tree[pos].right].left = pos;
tree[pos].right = temp;
}else{
if(tree[pos].left == -1) return; if(tree[temp].left == pos)
tree[temp].left = tree[pos].left;
else tree[temp].right = tree[pos].left; temp = tree[tree[pos].left].right;
tree[tree[pos].left].right = pos;
tree[pos].left = temp;
}
} void traverse(int num){
if(num == -1) return;
traverse(tree[num].left);
printf("%d\n", num);
traverse(tree[num].right);
} int main(){
int pos, num;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(int i = 0; i < n; ++i){
scanf("%d", &pos);
scanf("%d%d", &tree[pos].left, &tree[pos].right);
}
tree[11].left = 0; tree[11].right = -1; scanf("%d", &m);
while(m--){
scanf("%d%d", &pos, &num);
rotateTree(pos, num);
} traverse(tree[11].left);
printf("\n");
}
return 0;
}

后来看讨论区说能够不用旋转直接中序遍历。我对数据结构不熟,试了下果真能够。

#include <stdio.h>
struct Node{
int left, right;
} tree[12]; //第11个节点作为保存树根信息的节点
int t, n, m; void traverse(int num){
if(num == -1) return;
traverse(tree[num].left);
printf("%d\n", num);
traverse(tree[num].right);
} int main(){
int pos, num;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(int i = 0; i < n; ++i){
scanf("%d", &pos);
scanf("%d%d", &tree[pos].left, &tree[pos].right);
}
tree[11].left = 0; tree[11].right = -1; scanf("%d", &m);
while(m--)
scanf("%d%d", &pos, &num); traverse(tree[11].left);
printf("\n");
}
return 0;
}

NYOJ202 红黑树 【预购】的更多相关文章

  1. nyoj202——红黑树

    为了看懂这条题我还专门去看了看红黑树,结果大佬告诉我:左旋右旋不会影响中序遍历...... 然后就写了个简单的中序遍历...... #include <bits/stdc++.h> usi ...

  2. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  3. jdk源码分析红黑树——插入篇

    红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...

  4. 谈c++ pb_ds库(二) 红黑树大法好

    厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...

  5. 定时器管理:nginx的红黑树和libevent的堆

    libevent 发生超时后, while循环一次从堆顶del timer——直到最新调整的最小堆顶不是超时事件为止,(实际是del event),但是会稍后把这个timeout的 event放到ac ...

  6. 从2-3-4树到红黑树(下) Java与C的实现

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处   http://www.cnblogs.com/nullzx/ 相关博客: 从2-3-4树到红黑树(上) 从2-3-4树到红黑树(中) 1. 实现技 ...

  7. 红黑树/B+树/AVL树

    RB Tree 红黑树  :http://blog.csdn.net/very_2/article/details/5722682 Nginx的RBTree实现   :http://blog.csdn ...

  8. 论AVL树与红黑树

    首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...

  9. DataStructure——红黑树学习笔记

    1.前言 本文伪码和解释参考: http://blog.csdn.net/v_JULY_v/article/details/6105630 C实现的源码本文未贴出,请见: http://blog.cs ...

随机推荐

  1. Swift - 分段选择控件(UISegmentedControl)的用法

    1,选择控件的创建,并监听控件选择值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class ViewController: UIVie ...

  2. linux下安装node.js

    1.下载 wget http://nodejs.org/dist/v0.10.32/node-v0.10.32-linux-x64.tar.gz 2.解压 tar -xvf node-v0.10.32 ...

  3. linux df和du统计的空间不一致

    假设你发现是 /tmp/ 目录不对劲,那么就这样就可以查看:  lsof | grep /tmp 输出的结果中,注意某些含有“(deleted)”字样的记录,它们中的一部分就是罪魁祸首,将它们kill ...

  4. Nancy.Host的Web应用

    Nancy.Host实现脱离iis的Web应用 本篇将介绍如何使用Nancy.Host实现脱离iis的Web应用,在开源任务管理平台TaskManagerV2.0代码里面已经使用了Nancy.Host ...

  5. XML和对象属性互转的基类

    本人做了一个XML和对象属性互转的基类,现在放上来有兴趣拿去看一下,用法很简单,声明一个BaseConversion的子类,该子类与你想转换的对象相对应,然后覆盖基类的两个虚方法,然后在里面写元素与对 ...

  6. hibernate学习(一)

    一.准备工作:导入jar包 1.hibernate的jar包 位置: hibernate-release-5.0.2.Final\hibernate-release-5.0.2.Final\lib\r ...

  7. 图像编程学习笔记2——bmp位图平移

    以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序. 2.1 平移 平移(translation)变换大概是几何变换中最简单的一种了 ...

  8. 在WIN7系统的笔记本上建立WIFI热点

        成功与否的关键在于你是否依照顺序运行:       前置条件:右键"我的电脑"--"属性"--"设备管理器"--"网络适配 ...

  9. C++教材

    C++语言: 1.<Essential C++>:Stanley B.Lipman著. 旁枝暂略,主攻核心,轻薄短小.附习题与解答,适合刚開始学习的人. 2.<The C++ Pro ...

  10. 如果在线显示php源代码

    原文:如果在线显示php源代码 通过php提供的函数highlight_file和highlight_string实现