算法导论 红黑树 学习 旋转(二)
2017-02-14 15:32
330 查看
学习算法 还是建议看看算法导论
算法导论第三版 如果不看数学推导 仅看伪代码 难度还是适中
本系列只是记录我的学习心得 和伪代码转化代码的过程
深入学习 还是建议大家看看算法书籍 教程更加系统。
本文参考算法导论第13章节 红黑树
代码由本人写成
转载请标明出处
红黑树是一个带颜色的二叉树
有以下5点性能
1 每个节点或者红色或者黑色
2 根节点黑色
3 每个叶子节点(nil)为黑色
4 如果一个节点是红色的则它的两个子节点都是黑色
5 每个节点 该节点到子孙节点的路径上 黑色节点数目相同
如图
nil节点共享版本
隐藏nil节点
红黑树的结构与二叉树类似
但是增加了指向节点父节点的指针 和颜色记录
enum Color {
red = 1,
black
};
struct node {
Color color_;
std::shared_ptr<node> left_;
std::shared_ptr<node> right_;
std::shared_ptr<node> parent_;
int value_;
node() {
left_ = right_ = parent_ = nullptr;
value_ = -1;
color_ = black;
}
};
还创建以叶节点nil
打印函数 与二叉树变化不大
void PrinTree(std::shared_ptr<node> root) {
if (root == nil) {
return;
}
std::cout << root->value_ << " ";
if(root->left_!=nil)
PrinTree(root->left_);
if(root->right_ != nil)
PrinTree(root->right_);
}
旋转操作
旋转是保持平衡的最基本的操作 我们先从这里开始学习
在实际的操作旋转如图
伪代码如图
实际上就是
将Y的左子树 更改为X的右子树
X更改为Y的左子树
实际代码为
void RightRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->left_;
x->left_ = y->right_;
if (y->right_ != nil)
y->right_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil){
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->right_ = x;
x->parent_ = y;
}
我们来创建一个红黑树 测试下旋转操作(先不关注颜色 只关注旋转操作)
全部代码如下
#include "stdafx.h"
#include <memory>
#include <iostream>
using namespace std;
enum Color {
red = 1,
black
};
struct node {
Color color_;
std::shared_ptr<node> left_;
std::shared_ptr<node> right_;
std::shared_ptr<node> parent_;
int value_;
node() {
left_ = right_ = parent_ = nullptr;
value_ = -1;
color_ = black;
}
};
std::shared_ptr<node> nil(new node);
std::shared_ptr<node> CreateNode(Color color, int i) {
std::shared_ptr<node> p(new node);
p->color_ = color;
p->left_ = nil;
p->right_ = nil;
p->parent_ = nil;
p->value_ = i;
return p;
}
void RightRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->left_;
x->left_ = y->right_;
if (y->right_ != nil)
y->right_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->right_ = x;
x->parent_ = y;
}
void LeftRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->right_;
x->right_ = y->left_;
if (y->left_ != nil)
y->left_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->left_ = x;
x->parent_ = y;
}
void PrinTree(std::shared_ptr<node> root) {
if (root == nil) {
return;
}
std::cout << root->value_ << " ";
if (root->left_ != nil)
PrinTree(root->left_);
if (root->right_ != nil)
PrinTree(root->right_);
}
void TestLeftRotate1() {
std::shared_ptr<node> root = CreateNode(black, 1);
root->parent_ = nil;
std::shared_ptr<node> x = root;
root->right_ = CreateNode(red, 2);
root->right_->parent_ = root;
PrinTree(root);
std::cout << std::endl;
LeftRotate(root, x);
PrinTree(root);
std::cout << std::endl;
}
void TestRightRotate1() {
std::shared_ptr<node> root = CreateNode(black, 2);
root->parent_ = nil;
std::shared_ptr<node> x = root;
std::shared_ptr<node> y = CreateNode(red, 1);
root->left_ = y;
y->parent_ = x;
PrinTree(root);
std::cout << std::endl;
RightRotate(root, x);
PrinTree(root);
std::cout << std::endl;
}
int main()
{
TestLeftRotate1();
TestRightRotate1();
return 0;
}代码运行效果如图
由于左旋转与右旋转 是镜像映射的 这里仅仅介绍左旋转
左旋转后
再来一个多节点的旋转
#include <memory>
#include <iostream>
using namespace std;
enum Color {
red = 1,
black
};
struct node {
Color color_;
std::shared_ptr<node> left_;
std::shared_ptr<node> right_;
std::shared_ptr<node> parent_;
int value_;
node() {
left_ = right_ = parent_ = nullptr;
value_ = -1;
color_ = black;
}
};
std::shared_ptr<node> nil(new node);
std::shared_ptr<node> CreateNode(Color color, int i) {
std::shared_ptr<node> p(new node);
p->color_ = color;
p->left_ = nil;
p->right_ = nil;
p->parent_ = nil;
p->value_ = i;
return p;
}
void RightRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->left_;
x->left_ = y->right_;
if (y->right_ != nil)
y->right_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->right_ = x;
x->parent_ = y;
}
void LeftRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->right_;
x->right_ = y->left_;
if (y->left_ != nil)
y->left_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->left_ = x;
x->parent_ = y;
}
void PrinTree(std::shared_ptr<node> root) {
if (root == nil) {
return;
}
std::cout << root->value_ << " ";
if (root->left_ != nil)
PrinTree(root->left_);
if (root->right_ != nil)
PrinTree(root->right_);
}
void TestLeftRotate2() {
//测试 1 3 2 4
std::shared_ptr<node> root = CreateNode(black, 1);
root->parent_ = nil;
root->right_ = CreateNode(red, 3);
root->right_->parent_ = root;
std::shared_ptr<node> x = root->right_;
std::shared_ptr<node> y = CreateNode(red, 2);
x->left_ = y;
y->parent_ = x;
std::shared_ptr<node> z = CreateNode(red, 4);
x->right_ = z;
z->parent_ = x;
PrinTree(root);
std::cout << std::endl;
LeftRotate(root, x);
PrinTree(root);
std::cout << std::endl;
}
void TestRightRotate1() {
//测试 9 10 6 8 4 2 5
std::shared_ptr<node> root = CreateNode(black, 9);
root->parent_ = nil;
std::shared_ptr<node> a = root;
std::shared_ptr<node> b = CreateNode(black, 10);
a->right_ = b;
b->parent_ = a;
std::shared_ptr<node> c = CreateNode(black, 6);
a->left_ = c;
c->parent_ = a;
std::shared_ptr<node> d = CreateNode(black, 8);
c->right_ = d;
d->parent_ = c;
std::shared_ptr<node> e = CreateNode(black, 4);
c->left_ = e;
e->parent_ = c;
std::shared_ptr<node> f = CreateNode(black, 2);
e->left_ = f;
f->parent_ = e;
std::shared_ptr<node> g = CreateNode(black, 5);
e->right_ = g;
g->parent_ = e;
PrinTree(root);
std::cout << std::endl;
RightRotate(root, c);
PrinTree(root);
std::cout << std::endl;
}
int main()
{
TestLeftRotate1();
std::cout << std::endl;
TestRightRotate1();
return 0;
}
这里介绍右旋转 图示如图
节点6进行右旋转后
技术博客 http://blog.csdn.net/stecdeng
技术交流群 群号码:324164944 欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
算法导论第三版 如果不看数学推导 仅看伪代码 难度还是适中
本系列只是记录我的学习心得 和伪代码转化代码的过程
深入学习 还是建议大家看看算法书籍 教程更加系统。
本文参考算法导论第13章节 红黑树
代码由本人写成
转载请标明出处
红黑树是一个带颜色的二叉树
有以下5点性能
1 每个节点或者红色或者黑色
2 根节点黑色
3 每个叶子节点(nil)为黑色
4 如果一个节点是红色的则它的两个子节点都是黑色
5 每个节点 该节点到子孙节点的路径上 黑色节点数目相同
如图
nil节点共享版本
隐藏nil节点
红黑树的结构与二叉树类似
但是增加了指向节点父节点的指针 和颜色记录
enum Color {
red = 1,
black
};
struct node {
Color color_;
std::shared_ptr<node> left_;
std::shared_ptr<node> right_;
std::shared_ptr<node> parent_;
int value_;
node() {
left_ = right_ = parent_ = nullptr;
value_ = -1;
color_ = black;
}
};
还创建以叶节点nil
void PrinTree(std::shared_ptr<node> root) {
if (root == nil) {
return;
}
std::cout << root->value_ << " ";
if(root->left_!=nil)
PrinTree(root->left_);
if(root->right_ != nil)
PrinTree(root->right_);
}
旋转操作
旋转是保持平衡的最基本的操作 我们先从这里开始学习
在实际的操作旋转如图
伪代码如图
实际上就是
将Y的左子树 更改为X的右子树
X更改为Y的左子树
实际代码为
void RightRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->left_;
x->left_ = y->right_;
if (y->right_ != nil)
y->right_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil){
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->right_ = x;
x->parent_ = y;
}
我们来创建一个红黑树 测试下旋转操作(先不关注颜色 只关注旋转操作)
全部代码如下
#include "stdafx.h"
#include <memory>
#include <iostream>
using namespace std;
enum Color {
red = 1,
black
};
struct node {
Color color_;
std::shared_ptr<node> left_;
std::shared_ptr<node> right_;
std::shared_ptr<node> parent_;
int value_;
node() {
left_ = right_ = parent_ = nullptr;
value_ = -1;
color_ = black;
}
};
std::shared_ptr<node> nil(new node);
std::shared_ptr<node> CreateNode(Color color, int i) {
std::shared_ptr<node> p(new node);
p->color_ = color;
p->left_ = nil;
p->right_ = nil;
p->parent_ = nil;
p->value_ = i;
return p;
}
void RightRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->left_;
x->left_ = y->right_;
if (y->right_ != nil)
y->right_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->right_ = x;
x->parent_ = y;
}
void LeftRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->right_;
x->right_ = y->left_;
if (y->left_ != nil)
y->left_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->left_ = x;
x->parent_ = y;
}
void PrinTree(std::shared_ptr<node> root) {
if (root == nil) {
return;
}
std::cout << root->value_ << " ";
if (root->left_ != nil)
PrinTree(root->left_);
if (root->right_ != nil)
PrinTree(root->right_);
}
void TestLeftRotate1() {
std::shared_ptr<node> root = CreateNode(black, 1);
root->parent_ = nil;
std::shared_ptr<node> x = root;
root->right_ = CreateNode(red, 2);
root->right_->parent_ = root;
PrinTree(root);
std::cout << std::endl;
LeftRotate(root, x);
PrinTree(root);
std::cout << std::endl;
}
void TestRightRotate1() {
std::shared_ptr<node> root = CreateNode(black, 2);
root->parent_ = nil;
std::shared_ptr<node> x = root;
std::shared_ptr<node> y = CreateNode(red, 1);
root->left_ = y;
y->parent_ = x;
PrinTree(root);
std::cout << std::endl;
RightRotate(root, x);
PrinTree(root);
std::cout << std::endl;
}
int main()
{
TestLeftRotate1();
TestRightRotate1();
return 0;
}代码运行效果如图
由于左旋转与右旋转 是镜像映射的 这里仅仅介绍左旋转
左旋转后
再来一个多节点的旋转
#include <memory>
#include <iostream>
using namespace std;
enum Color {
red = 1,
black
};
struct node {
Color color_;
std::shared_ptr<node> left_;
std::shared_ptr<node> right_;
std::shared_ptr<node> parent_;
int value_;
node() {
left_ = right_ = parent_ = nullptr;
value_ = -1;
color_ = black;
}
};
std::shared_ptr<node> nil(new node);
std::shared_ptr<node> CreateNode(Color color, int i) {
std::shared_ptr<node> p(new node);
p->color_ = color;
p->left_ = nil;
p->right_ = nil;
p->parent_ = nil;
p->value_ = i;
return p;
}
void RightRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->left_;
x->left_ = y->right_;
if (y->right_ != nil)
y->right_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->right_ = x;
x->parent_ = y;
}
void LeftRotate(std::shared_ptr<node>& root, std::shared_ptr<node> x) {
std::shared_ptr<node> y = x->right_;
x->right_ = y->left_;
if (y->left_ != nil)
y->left_->parent_ = x;
y->parent_ = x->parent_;
if (x->parent_ == nil) {
root = y;
}
else if (x->parent_->left_ == x) {
x->parent_->left_ = y;
}
else {
x->parent_->right_ = y;
}
y->left_ = x;
x->parent_ = y;
}
void PrinTree(std::shared_ptr<node> root) {
if (root == nil) {
return;
}
std::cout << root->value_ << " ";
if (root->left_ != nil)
PrinTree(root->left_);
if (root->right_ != nil)
PrinTree(root->right_);
}
void TestLeftRotate2() {
//测试 1 3 2 4
std::shared_ptr<node> root = CreateNode(black, 1);
root->parent_ = nil;
root->right_ = CreateNode(red, 3);
root->right_->parent_ = root;
std::shared_ptr<node> x = root->right_;
std::shared_ptr<node> y = CreateNode(red, 2);
x->left_ = y;
y->parent_ = x;
std::shared_ptr<node> z = CreateNode(red, 4);
x->right_ = z;
z->parent_ = x;
PrinTree(root);
std::cout << std::endl;
LeftRotate(root, x);
PrinTree(root);
std::cout << std::endl;
}
void TestRightRotate1() {
//测试 9 10 6 8 4 2 5
std::shared_ptr<node> root = CreateNode(black, 9);
root->parent_ = nil;
std::shared_ptr<node> a = root;
std::shared_ptr<node> b = CreateNode(black, 10);
a->right_ = b;
b->parent_ = a;
std::shared_ptr<node> c = CreateNode(black, 6);
a->left_ = c;
c->parent_ = a;
std::shared_ptr<node> d = CreateNode(black, 8);
c->right_ = d;
d->parent_ = c;
std::shared_ptr<node> e = CreateNode(black, 4);
c->left_ = e;
e->parent_ = c;
std::shared_ptr<node> f = CreateNode(black, 2);
e->left_ = f;
f->parent_ = e;
std::shared_ptr<node> g = CreateNode(black, 5);
e->right_ = g;
g->parent_ = e;
PrinTree(root);
std::cout << std::endl;
RightRotate(root, c);
PrinTree(root);
std::cout << std::endl;
}
int main()
{
TestLeftRotate1();
std::cout << std::endl;
TestRightRotate1();
return 0;
}
这里介绍右旋转 图示如图
节点6进行右旋转后
技术博客 http://blog.csdn.net/stecdeng
技术交流群 群号码:324164944 欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
相关文章推荐
- 浅析时钟向量算法
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- Android数据加密之异或加密算法的实现方法
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法