由于红黑树的每一处结构都能唯一的转换为2-3-4树(即4阶B树)中对应的结构因此每一棵红黑树都唯一对应一棵2-3-4树,但反之,对应于只有两个关键码的2-3-4树节点的2-3-4树结构能够转换为两种不同的红黑树结构(两个关键码左边为红黑树中黑色节点,右边为红色节点或相反),所以一般情况下对于一棵2-3-4树,往往有多棵红黑树与之对应。本文要介绍的就是将红黑树转换为2-3-4树或将2-3-4树转换为与之对应的多棵红黑树的算法。算法的基本思想是后序遍历红黑树或2-3-4树,自底向下将每一种红黑树(2-3-4树)构造转换为与之对应的2-3-4树(红黑树)构造,转换构造的过程中需要使用自底向下的过程中已经完成转换的构造,并把这些构造进行组合以生成新的高层构造,该过程会一直持续到红黑树或2-3-4树的根节点。
由于红黑树对应的2-3-4树中总是把黑色节点的红色子节点提升到和黑色节点同一层的同一个2-3-4树节点中,而由红黑树的特性,红色节点没有红色子节点,这就使得在2-3-4树中,红黑树从根节点到叶节点任意一条路径上的单个红色节点都被压缩到了上一层的黑色父节点上,这意味着与红黑树对应的2-3-4树高度(不包括失败节点)恰为红黑树的黑高度(红黑树任意一条从根节点到外节点的路径上黑色节点总数)。此外,以下算法还可以保证红黑树转换所得的2-3-4树满足4阶B树的所有特性,由2-3-4树转换所得红黑树也满足红黑树的所有特性,要证明一点只要从下至上使用归纳法,证明在低层转换构造满足2-3-4树或红黑树的某些特性的情况下由低层构造生成的高层构造同样满足这些特性,证明会一直持续到红黑树或2-3-4树根节点,从而确定转换所得树确实满足红黑树和2-3-4树的所有要求。证明是简单的,机械的,这里就不详细说明了。
用归纳法可以自底向上证明如果2-3-4树对应多棵红黑树,则算法转换得到的红黑树必两两不同,因此无需剔除重复的红黑树
转换代码如下:
#include <iostream>
#include <vector>
#include <map>
#include <random>
#include <memory>
using namespace std;
#include "RBTree.h"
#include "BTree.h"
enum class Type { RED, BLACK };
template <typename T>
struct RedSubTreeInfo
{
BTreeNode<T>* partBTreeForBlackSubTree_left = nullptr; //红色节点左子树转换生成的2-3-4树构造
BTreeNode<T>* partBTreeForBlackSubTree_right = nullptr; //红色节点右子树转换生成的2-3-4树构造
RedSubTreeInfo(BTreeNode<T>* pl, BTreeNode<T>* pr) :partBTreeForBlackSubTree_left(pl), partBTreeForBlackSubTree_right(pr) {}
};
template <typename T>
struct SubTreeInfo //红黑树某节点的低层2-3-4树构造信息
{
Type id; //该构造对应红黑树红色节点还是黑色节点
union
{
RedSubTreeInfo<T> red_sub_tree_info; //红色节点对应的2-3-4树构造
BTreeNode<T>* partBTreeForBlackSubTree; //黑色节点对应的2-3-4树构造
};
SubTreeInfo(Type t, BTreeNode<T>* p) : id(t), partBTreeForBlackSubTree(p) {}
SubTreeInfo(Type t, BTreeNode<T>* pl, BTreeNode<T>* pr) :id(t)
{
new (&red_sub_tree_info) RedSubTreeInfo<T>(pl, pr);
}
~SubTreeInfo()
{
if (id == Type::RED)
{
red_sub_tree_info.~RedSubTreeInfo();
}
}
};
template <typename T>
RBTreeNode<T>* copyRBTree(RBTreeNode<T>* root)
{
if (root == nullptr)
return nullptr;
RBTreeNode<T>* _new = new RBTreeNode<T>(*root);
_new->left = copyRBTree(root->left);
_new->right = copyRBTree(root->right);
return _new;
}
template <typename T>
void delRBTree(RBTreeNode<T>* root)
{
if (root == nullptr)
return;
delRBTree(root->left);
delRBTree(root->right);
delete root;
}
template <typename T>
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> SearchBTreeNodeOther(BTreeNode<T>* ptr, pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> d) //返回值:尾后+fasle表示第一指针,尾后+true表示失败,非尾后+true即为对应指针
{
typename vector<pair<T, BTreeNode<T>*>>::iterator m; //实参pair:尾后+false表示从第一指针后一指针开始搜索,尾后+true表示从头搜索,非尾后+true表示从非尾后后一位置开始搜索
if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
return { d.first, false };
}
else if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), false))
{
m = ptr->branch_data->keyptrmap.begin();
}
else
{
m = d.first;
++m;
}
return { m, true };
}
template <typename T>
shared_ptr<vector<RBTreeNode<T>*>> BTreeToRBTree(BTreeNode<T>* root) //将2-3-4树转换为与之对应的所有红黑树
{
struct memory
{
BTreeNode<T>* p; //遍历2-3-4树时对应层节点指针
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> direction; //遍历时在该层的前进方向(此时正在向下遍历那一棵2-3-4子树)
vector<shared_ptr<vector<RBTreeNode<T>*>>> RBTreeForEverySubTree; //存放2-3-4树节点的每一个子节点对应的所有红黑树构造
memory(BTreeNode<T>* p, const pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>& d) :p(p), direction(d) {}
};
shared_ptr<vector<RBTreeNode<T>*>> AllRBTreeForBTree = make_shared<vector<RBTreeNode<T>*>>(); //存放当前2-3-4树对应的所有红黑树
BTreeNode<T>* ptr = root;
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> d;
if (ptr->NodeFlag != BTreeNode<T>::flag::leaf)
{
d.first = ptr->branch_data->keyptrmap.end();
d.second = true;
}
BTreeNode<T>* const dest = ptr;
stack<memory> arrange;
while (true)
{
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> result;
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf ? true : (result = SearchBTreeNodeOther(ptr, d)) == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf) //生成2-3-4树叶节点对应的红黑树构造,若该叶节点不为根节点
{ //则把构造信息传递至上层节点,若为根节点,直接返回2-3-4树对应的所有红黑树
typename vector<T>::iterator it = ptr->leaf_data->begin();
RBTreeNode<T>* temp = nullptr;
if (ptr->leaf_data->size() == 1) //节点只有一个关键码,生成单一黑节点构造
{
temp = new RBTreeNode<T>(*it, ColorFlag::BLACK);
}
else if (ptr->leaf_data->size() == 2) //两个关键码,生成红-黑或黑-红构造
{
temp = new RBTreeNode<T>(*it, ColorFlag::BLACK);
++it;
temp->right = new RBTreeNode<T>(*it, ColorFlag::RED);
if (ptr == dest)
{
AllRBTreeForBTree->push_back(temp);
}
else
{
arrange.top().RBTreeForEverySubTree.push_back(make_shared<vector<RBTreeNode<T>*>>());
arrange.top().RBTreeForEverySubTree.back()->push_back(temp);
}
temp = new RBTreeNode<T>(*it, ColorFlag::BLACK);
--it;
temp->left = new RBTreeNode<T>(*it, ColorFlag::RED);
}
else if (ptr->leaf_data->size() == 3) //三个关键码,生成红-黑-红构造
{
++it;
temp = new RBTreeNode<T>(*it, ColorFlag::BLACK);
--it;
temp->left = new RBTreeNode<T>(*it, ColorFlag::RED);
++it; ++it;
temp->right = new RBTreeNode<T>(*it, ColorFlag::RED);
}
if (ptr == dest)
{
AllRBTreeForBTree->push_back(temp);
return AllRBTreeForBTree;
}
else
{
if (ptr->leaf_data->size() != 2)
arrange.top().RBTreeForEverySubTree.push_back(make_shared<vector<RBTreeNode<T>*>>());
arrange.top().RBTreeForEverySubTree.back()->push_back(temp); //本层节点对应构造传递至上层节点,若该分支节点不为根节点
} //则把构造信息传递至上层节点,若为根节点直接返回根节点对应红黑树构造
}
else
{
typename vector<pair<T, BTreeNode<T>*>>::iterator it = ptr->branch_data->keyptrmap.begin();
shared_ptr<vector<RBTreeNode<T>*>> RBTreePtr = nullptr; //生成2-3-4树分支节点对应红黑树构造
size_t index = 0;
if (ptr->branch_data->keyptrmap.size() == 1) //同上
{
RBTreePtr = make_shared<vector<RBTreeNode<T>*>>(arrange.top().RBTreeForEverySubTree[0]->size() * arrange.top().RBTreeForEverySubTree[1]->size());
for (size_t q = 0; q != arrange.top().RBTreeForEverySubTree[0]->size(); ++q)
{
for (size_t p = 0; p != arrange.top().RBTreeForEverySubTree[1]->size(); ++p)
{
RBTreeNode<T>* temp = new RBTreeNode<T>(it->first, ColorFlag::BLACK);
if (p == 0)
temp->left = (*arrange.top().RBTreeForEverySubTree[0])[q];
else
temp->left = copyRBTree((*arrange.top().RBTreeForEverySubTree[0])[q]);
if (q == 0)
temp->right = (*arrange.top().RBTreeForEverySubTree[1])[p];
else
temp->right = copyRBTree((*arrange.top().RBTreeForEverySubTree[1])[p]);
(*RBTreePtr)[index++] = temp;
}
}
}
else if (ptr->branch_data->keyptrmap.size() == 2) //同上
{
RBTreePtr = make_shared<vector<RBTreeNode<T>*>>(arrange.top().RBTreeForEverySubTree[0]->size() * arrange.top().RBTreeForEverySubTree[1]->size() * arrange.top().RBTreeForEverySubTree[2]->size() * 2);
for (size_t q = 0; q != arrange.top().RBTreeForEverySubTree[0]->size(); ++q)
{
for (size_t p = 0; p != arrange.top().RBTreeForEverySubTree[1]->size(); ++p)
{
for (size_t m = 0; m != arrange.top().RBTreeForEverySubTree[2]->size(); ++m)
{
RBTreeNode<T>* temp = new RBTreeNode<T>(it->first, ColorFlag::BLACK);
++it;
temp->right = new RBTreeNode<T>(it->first, ColorFlag::RED);
--it;
if (p == 0 && m == 0)
temp->left = (*arrange.top().RBTreeForEverySubTree[0])[q];
else
temp->left = copyRBTree((*arrange.top().RBTreeForEverySubTree[0])[q]);
if (q == 0 && m == 0)
temp->right->left = (*arrange.top().RBTreeForEverySubTree[1])[p];
else
temp->right->left = copyRBTree((*arrange.top().RBTreeForEverySubTree[1])[p]);
if (q == 0 && p == 0)
temp->right->right = (*arrange.top().RBTreeForEverySubTree[2])[m];
else
temp->right->right = copyRBTree((*arrange.top().RBTreeForEverySubTree[2])[m]);
(*RBTreePtr)[index++] = temp;
}
}
}
for (size_t q = 0; q != arrange.top().RBTreeForEverySubTree[0]->size(); ++q)
{
for (size_t p = 0; p != arrange.top().RBTreeForEverySubTree[1]->size(); ++p)
{
for (size_t m = 0; m != arrange.top().RBTreeForEverySubTree[2]->size(); ++m)
{
++it;
RBTreeNode<T>* temp = new RBTreeNode<T>(it->first, ColorFlag::BLACK);
--it;
temp->left = new RBTreeNode<T>(it->first, ColorFlag::RED);
temp->right = copyRBTree((*arrange.top().RBTreeForEverySubTree[2])[m]);
temp->left->right = copyRBTree((*arrange.top().RBTreeForEverySubTree[1])[p]);
temp->left->left = copyRBTree((*arrange.top().RBTreeForEverySubTree[0])[q]);
(*RBTreePtr)[index++] = temp;
}
}
}
}
else if (ptr->branch_data->keyptrmap.size() == 3) //同上
{
RBTreePtr = make_shared<vector<RBTreeNode<T>*>>(arrange.top().RBTreeForEverySubTree[0]->size() * arrange.top().RBTreeForEverySubTree[1]->size() * arrange.top().RBTreeForEverySubTree[2]->size() * arrange.top().RBTreeForEverySubTree[3]->size());
++it;
for (size_t q = 0; q != arrange.top().RBTreeForEverySubTree[0]->size(); ++q)
{
for (size_t p = 0; p != arrange.top().RBTreeForEverySubTree[1]->size(); ++p)
{
for (size_t m = 0; m != arrange.top().RBTreeForEverySubTree[2]->size(); ++m)
{
for (size_t v = 0; v != arrange.top().RBTreeForEverySubTree[3]->size(); ++v)
{
RBTreeNode<T>* temp = new RBTreeNode<T>(it->first, ColorFlag::BLACK);
--it;
temp->left = new RBTreeNode<T>(it->first, ColorFlag::RED);
++it; ++it;
temp->right = new RBTreeNode<T>(it->first, ColorFlag::RED);
--it;
if (p == 0 && m == 0 && v == 0)
temp->left->left = (*arrange.top().RBTreeForEverySubTree[0])[q];
else
temp->left->left = copyRBTree((*arrange.top().RBTreeForEverySubTree[0])[q]);
if (q == 0 && m == 0 && v == 0)
temp->left->right = (*arrange.top().RBTreeForEverySubTree[1])[p];
else
temp->left->right = copyRBTree((*arrange.top().RBTreeForEverySubTree[1])[p]);
if (q == 0 && p == 0 && v == 0)
temp->right->left = (*arrange.top().RBTreeForEverySubTree[2])[m];
else
temp->right->left = copyRBTree((*arrange.top().RBTreeForEverySubTree[2])[m]);
if (q == 0 && p == 0 && m == 0)
temp->right->right = (*arrange.top().RBTreeForEverySubTree[3])[v];
else
temp->right->right = copyRBTree((*arrange.top().RBTreeForEverySubTree[3])[v]);
(*RBTreePtr)[index++] = temp;
}
}
}
}
}
arrange.pop();
if (arrange.empty() == true)
return RBTreePtr;
arrange.top().RBTreeForEverySubTree.push_back(RBTreePtr);
}
ptr = arrange.top().p;
d = arrange.top().direction;
}
else
{
if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
arrange.push(memory(ptr, result));
ptr = ptr->branch_data->p;
}
else
{
arrange.top().direction = result;
ptr = result.first->second;
}
if (ptr->NodeFlag != BTreeNode<T>::flag::leaf)
{
d = pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true);
}
}
}
}
template <typename T>
struct StackNode
{
RBTreeNode<T>* ptr = nullptr; //每一层红黑树节点指针
int direction = 0;
SubTreeInfo<T>* left_sub = nullptr; //左子树2-3-4树构造
StackNode(RBTreeNode<T>* p, int d) :ptr(p), direction(d) {}
~StackNode()
{
delete left_sub;
}
};
template <typename T>
BTreeNode<T>* RBTreeToBTree(RBTreeNode<T>* root) //将红黑树转换为对应2-3-4树
{
RBTreeNode<T>* ptr = root;
RBTreeNode<T>* const dest = ptr;
stack<StackNode<T>> work_stack;
int d = 0;
SubTreeInfo<T>* right_sub = nullptr; //右子树2-3-4树构造
while (true)
{
int result;
if ((result = Searchd(ptr, d)) == 0)
{
if (ptr == dest)
{
if (d == 0) //根节点为叶节点,直接返回对应2-3-4树构造
{
BTreeNode<T>* temp_ptr = new BTreeNode<T>(BTreeNode<T>::flag::leaf);
temp_ptr->leaf_data->push_back(ptr->data);
return temp_ptr;
}
}
if (ptr->color == ColorFlag::BLACK)
{
BTreeNode<T>* temp_ptr = nullptr;
if (d != 0) //分支节点,可以为根节点,为根节点时生成根节点对应2-3-4树并返回,否则生成分支节点对应2-3-4树构造并传递至上层栈节点
{
if (ptr->left == nullptr || ptr->right == nullptr)
{
temp_ptr = new BTreeNode<T>(BTreeNode<T>::flag::leaf);
if (ptr->left == nullptr)
{
temp_ptr->leaf_data->push_back(ptr->data);
temp_ptr->leaf_data->push_back(ptr->right->data);
}
else
{
temp_ptr->leaf_data->push_back(ptr->left->data);
temp_ptr->leaf_data->push_back(ptr->data);
}
}
else
{
if (ptr->left->color != ColorFlag::BLACK && ptr->right->color == ColorFlag::RED && ptr->left->left == nullptr)
{
temp_ptr = new BTreeNode<T>(BTreeNode<T>::flag::leaf);
temp_ptr->leaf_data->push_back(ptr->left->data);
temp_ptr->leaf_data->push_back(ptr->data);
temp_ptr->leaf_data->push_back(ptr->right->data);
}
else
{
temp_ptr = new BTreeNode<T>(BTreeNode<T>::flag::branch);
if (ptr->left->color == ColorFlag::BLACK)
{
temp_ptr->branch_data->p = work_stack.top().left_sub->partBTreeForBlackSubTree;
}
else
{
temp_ptr->branch_data->p = work_stack.top().left_sub->red_sub_tree_info.partBTreeForBlackSubTree_left;
temp_ptr->branch_data->keyptrmap.push_back(make_pair(ptr->left->data, work_stack.top().left_sub->red_sub_tree_info.partBTreeForBlackSubTree_right));
}
if (ptr->right->color == ColorFlag::RED)
{
temp_ptr->branch_data->keyptrmap.push_back(make_pair(ptr->data, right_sub->red_sub_tree_info.partBTreeForBlackSubTree_left));
temp_ptr->branch_data->keyptrmap.push_back(make_pair(ptr->right->data, right_sub->red_sub_tree_info.partBTreeForBlackSubTree_right));
}
else
{
temp_ptr->branch_data->keyptrmap.push_back(make_pair(ptr->data, right_sub->partBTreeForBlackSubTree));
}
}
}
work_stack.pop();
if (work_stack.empty() == true)
return temp_ptr;
}
else
{
temp_ptr = new BTreeNode<T>(BTreeNode<T>::flag::leaf);
temp_ptr->leaf_data->push_back(ptr->data);
}
if (work_stack.top().direction == 1)
{
work_stack.top().left_sub = new SubTreeInfo<T>(Type::BLACK, temp_ptr);
}
else if (work_stack.top().direction == 2)
{
right_sub = new SubTreeInfo<T>(Type::BLACK, temp_ptr);
}
}
else
{
if (d != 0)
{
BTreeNode<T>* temp1 = work_stack.top().left_sub->partBTreeForBlackSubTree;
BTreeNode<T>* temp2 = right_sub->partBTreeForBlackSubTree;
work_stack.pop();
if (work_stack.top().direction == 1)
{
work_stack.top().left_sub = new SubTreeInfo<T>(Type::RED, temp1, temp2);
}
else if (work_stack.top().direction == 2)
{
right_sub = new SubTreeInfo<T>(Type::RED, temp1, temp2);
}
}//非根叶节点,为红色此时不必生成构造并向上传递
}
ptr = work_stack.top().ptr;
d = work_stack.top().direction;
}
else
{
if (d == 0)
{
work_stack.push(StackNode<T>(ptr, result));
if (work_stack.top().direction == 1)
ptr = ptr->left;
else
ptr = ptr->right;
}
else
{
work_stack.top().direction = 2;
ptr = ptr->right;
}
d = 0;
}
}
}
int main() //测试main函数
{
unsigned r = 1000;
for (unsigned N = 1; N <= r; ++N)
{
vector<TYPE> insertvalue(N);
for (unsigned i = 0; i < insertvalue.size(); ++i)
{
insertvalue[i] = i + 1;
}
shuffle(insertvalue.begin(), insertvalue.end(), default_random_engine());
RBTreeNode<TYPE>* root = nullptr;
for (vector<TYPE>::const_iterator p = insertvalue.cbegin(); p != insertvalue.cend(); ++p) //插入建立红黑树
{
root = InsertRB(root, *p);
cout << "插入" << *p << endl;
}
cout << endl;
BTreeNode<TYPE>* t = RBTreeToBTree(root); //红黑树转换为2-3-4树
cout << "已将红黑树转换为对应2-3-4树" << endl;
if (isBTree(t))
{
cout << "红黑树到2-3-4树转换结果正确" << endl;
}
else
{
cout << "红黑树到2-3-4树转换结果错误" << endl;
exit(-1);
}
vector<TYPE> seq;
cout << "转换后的2-3-4树中所有关键码为:";
printBTreeKey(t, seq);
cout << endl;
if (seq.size() != N)
{
cout << "ERROR" << endl;
exit(-1);
}
for (size_t i = 0; i < seq.size(); ++i)
{
if (i + 1 != seq[i])
{
cout << "ERROR" << endl;
exit(-1);
}
}
cout << "OK" << endl;
/*shared_ptr<vector<RBTreeNode<TYPE>*>> v = BTreeToRBTree(t); //2-3-4树转换为对应所有红黑树
cout << "已将2-3-4树转换为其对应的所有红黑树" << endl;
for (vector<RBTreeNode<TYPE>*>::iterator m = v->begin(); m != v->end(); ++m) //判断转换所得树是否满足红黑树所有特性
{
if (!isRB(*m))
{
cout << "2-3-4到红黑树转换错误" << endl;
exit(-1);
}
}
cout << "2-3-4树到红黑树转换正确!" << endl;
/*for (size_t i = 0; i< v->size() - 1; ++i)
{
for (size_t j = i + 1; j < v->size(); ++j)
{
if (RBTreeEqual((*v)[i], (*v)[j]))
{
cout << "错误,转换后的红黑树中存在相等的两棵红黑树" << endl;
exit(-1);
}
}
}*/
/*size_t i = 0;
for (; i < (*v).size(); ++i)
{
if (RBTreeEqual(root, (*v)[i]))
{
break;
}
}
if (i == v->size())
{
cout << "错误,转换后的红黑树中没有原红黑树" << endl;
exit(-1);
}
cout << "转换后的红黑树共有" << v->size() << "棵" << endl;
for (vector<RBTreeNode<TYPE>*>::iterator m = v->begin(); m != v->end(); ++m) //判断转换所得树是否满足红黑树所有特性
{
delRBTree(*m);
}
cout << "销毁成功!" << endl;*/
}
return 0;
}
以下代码中头文件RBTree.h和BTree.h中的内容
BTree.h
#include <iostream>
#include <utility>
#include <stack>
#include <vector>
#include <algorithm>
#include <ctime>
#include <random>
using namespace std;
const int M = 4; //B树阶数
template <typename T>
struct BTreeNode
{
struct BranchNode
{
BTreeNode* p;
vector<pair<T, BTreeNode<T>*>> keyptrmap; //节点数据域和指针域
BranchNode() :keyptrmap(), p(nullptr) {}
};
union
{
vector<T>* leaf_data;
BranchNode* branch_data;
};
enum flag { leaf, branch } NodeFlag; //节点标志叶节点or分支节点
BTreeNode(flag type_of_node)
{
NodeFlag = type_of_node;
if (type_of_node == branch)
{
branch_data = new BranchNode();
}
else
{
leaf_data = new vector<T>();
}
}
~BTreeNode()
{
if (NodeFlag == branch)
{
delete branch_data;
}
else
{
delete leaf_data;
}
}
};
template <typename T>
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> SearchBTreeNode(BTreeNode<T>* ptr, pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> d) //返回值:尾后+fasle表示第一指针,尾后+true表示失败,非尾后+true即为对应指针
{
typename vector<pair<T, BTreeNode<T>*>>::iterator m; //实参pair:尾后+false表示从第一指针后一指针开始搜索,尾后+true表示从头搜索,非尾后+true表示从非尾后后一位置开始搜索
if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
if (ptr->branch_data->p != nullptr)
return { d.first, false };
m = ptr->branch_data->keyptrmap.begin();
}
else if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), false))
{
m = ptr->branch_data->keyptrmap.begin();
}
else
{
m = d.first;
++m;
}
for (; m != ptr->branch_data->keyptrmap.end(); ++m)
{
if (m->second != nullptr)
return { m, true };
}
return { m, true };
}
template <typename T>
bool leafKeyFromSmallToBig(BTreeNode<T>* leaf)
{
typename vector<T>::iterator before = leaf->leaf_data->begin();
typename vector<T>::iterator after = before + 1;
for (; after != leaf->leaf_data->end(); before = after, ++after)
{
if (*before >= *after)
return false;
}
return true;
}
template <typename T>
bool isBTree(BTreeNode<T>* root) //判断给定多叉树是否为B树
{
struct memory
{
BTreeNode<T>* p;
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> direction;
T nodemin; //节点代表子树中最小值
memory(BTreeNode<T>* p, const pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>& d) :p(p), direction(d) {}
};
BTreeNode<T>* ptr = root;
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> d;
if (ptr->NodeFlag != BTreeNode<T>::flag::leaf)
{
d.first = ptr->branch_data->keyptrmap.end();
d.second = true;
}
T min; //节点某子树中最小节点值
T max; //节点某子树中最大节点值
BTreeNode<T>* const dest = ptr;
stack<memory> arrange;
bool TF = false;
int level = 0;
int beforelevel = 0;
while (true)
{
pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool> result;
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf ? true : (result = SearchBTreeNode(ptr, d)) == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
if (ptr == dest)
{
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf)
{
if (1 <= ptr->leaf_data->size() && ptr->leaf_data->size() <= M - 1)
{
if (leafKeyFromSmallToBig(ptr))
return true;
cout << "根叶节点关键码没有从小到大排列,非B树" << endl;
return false;
}
else
{
cout << "当前树只有根节点,但根节点子树数量不符合要求,非B树" << endl;
return false;
}
}
else
{
if (1 <= ptr->branch_data->keyptrmap.size() && ptr->branch_data->keyptrmap.size() <= M - 1)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = ptr->branch_data->keyptrmap.end();
--temp;
if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(temp, true))
{
if (min > temp->first)
{
return true;
}
else
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
else
{
cout << "失败节点不在同一层,非B树" << endl;
return false;
}
}
else
{
cout << "当前树根节点子树数量不符合要求,非B树";
return false;
}
}
}
else
{
if (ptr->NodeFlag == BTreeNode<T>::flag::leaf)
{
++level;
if (TF == false)
{
beforelevel = level;
TF = true;
}
else
{
if (level != beforelevel)
{
cout << "失败节点不在同一层,非B树" << endl;
return false;
}
}
if ((M + 1) / 2 - 1 <= ptr->leaf_data->size() && ptr->leaf_data->size() <= M - 1)
{
if (leafKeyFromSmallToBig(ptr) == false)
{
cout << "当前树叶结点关键码没有从小到大排列,非B树" << endl;
return false;
}
if (arrange.top().direction == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(arrange.top().p->branch_data->keyptrmap.end(), false))
{
arrange.top().nodemin = *(ptr->leaf_data->begin());
}
min = *(ptr->leaf_data->begin());
max = *(--ptr->leaf_data->end());
}
else
{
cout << "当前树叶节点数量不符合要求,非B树" << endl;
return false;
}
}
else
{
if ((M + 1) / 2 - 1 <= ptr->branch_data->keyptrmap.size() && ptr->branch_data->keyptrmap.size() <= M - 1)
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = ptr->branch_data->keyptrmap.end();
--temp;
if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(temp, true))
{
if (min > temp->first)
{
min = arrange.top().nodemin;
arrange.pop();
if (arrange.top().direction == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(arrange.top().p->branch_data->keyptrmap.end(), false))
{
arrange.top().nodemin = min;
}
}
else
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
else
{
cout << "失败节点不在同一层,非B树" << endl;
return false;
}
}
else
{
cout << "当前树分支节点子树数量不符合要求,非B树" << endl;
return false;
}
}
--level;
ptr = arrange.top().p;
d = arrange.top().direction;
}
}
else
{
if (d == pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true))
{
if (result != pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), false))
{
cout << "失败节点不在同一层,非B树" << endl;
return false;
}
arrange.push(memory(ptr, result));
ptr = ptr->branch_data->p;
++level;
}
else
{
typename vector<pair<T, BTreeNode<T>*>>::iterator temp = result.first;
if (d.first == ptr->branch_data->keyptrmap.end())
{
if (temp == ptr->branch_data->keyptrmap.begin())
{
if (!(max < temp->first))
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
else
{
cout << "失败节点不在同一层,非B树" << endl;
return false;
}
}
else
{
--temp;
if (temp == d.first)
{
++temp;
if (!(max < temp->first && min > d.first->first))
{
cout << "当前树不是" << M << "路搜索树,非B树" << endl;
return false;
}
}
else
{
cout << "失败节点不在同一层,非B树" << endl;
return false;
}
}
arrange.top().direction = pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(temp, true);
ptr = temp->second;
}
if (ptr->NodeFlag != BTreeNode<T>::flag::leaf)
{
d = pair<typename vector<pair<T, BTreeNode<T>*>>::iterator, bool>(ptr->branch_data->keyptrmap.end(), true);
}
}
}
}
RBTree.h
#include <string>
#include <vector>
#include <iostream>
#include <stack>
#include <random>
#include <ctime>
using namespace std;
#define TYPE int
enum ColorFlag { RED, BLACK };
template <typename T>
struct RBTreeNode
{
T data; //节点数据域
ColorFlag color; //节点颜色
RBTreeNode* left;
RBTreeNode* right;
RBTreeNode(T d, ColorFlag c) :data(d), color(c), left(nullptr), right(nullptr) {}
RBTreeNode(const RBTreeNode& be_copied) : data(be_copied.data), color(be_copied.color), left(nullptr), right(nullptr) {}
};
template <typename T>
void RotateLR(RBTreeNode<T>*& ptr) //对以ptr为根的子树执行先左后右双旋转,ptr成为旋转后新树根节点指针
{
RBTreeNode<T>* p = ptr->left;
RBTreeNode<T>* q = p->right;
p->right = q->left;
q->left = p;
ptr->left = q->right;
q->right = ptr;
ptr = q;
}
template <typename T>
void RotateRL(RBTreeNode<T>*& ptr) //对以ptr为根的子树执行先右后左双旋转,ptr成为旋转后新树根节点指针
{
RBTreeNode<T>* p = ptr->right;
RBTreeNode<T>* q = p->left;
p->left = q->right;
q->right = p;
ptr->right = q->left;
q->left = ptr;
ptr = q;
}
template <typename T>
void RotateR(RBTreeNode<T>*& ptr) //对以ptr为根的子树执行右单旋转,ptr成为旋转后新树根节点指针
{
RBTreeNode<T>* p = ptr->left;
ptr->left = p->right;
p->right = ptr;
ptr = p;
}
template <typename T>
void RotateL(RBTreeNode<T>*& ptr) //对以ptr为根的子树执行左单旋转, ptr成为旋转后新树根节点指针
{
RBTreeNode<T>*p = ptr->right;
ptr->right = p->left;
p->left = ptr;
ptr = p;
}
bool examineBlackHeight(bool& TF, int& preroadblacknum, const int& blacknum)
{
if (TF == false)
{
TF = true;
preroadblacknum = blacknum;
}
else
{
if (preroadblacknum != blacknum)
{
cout << "从根节点到外节点的路径上黑节点数目不等,非红黑树" << endl;
return false;
}
}
return true;
}
template <typename T>
void addBlackNum(RBTreeNode<T>* ptr, int& blacknum)
{
if (ptr->color == ColorFlag::BLACK)
++blacknum;
}
template <typename T>
void reduceBlackNum(RBTreeNode<T>* ptr, int& blacknum)
{
if (ptr->color == ColorFlag::BLACK)
--blacknum;
}
template <typename T>
int Searchd(RBTreeNode<T>* ptr, int d)
{
if (d == 2)
return 0;
else
{
if (d == 1)
{
if (ptr->right == nullptr)
return 0;
else
return 2;
}
else
{
if (ptr->left != nullptr)
return 1;
else
{
if (ptr->right != nullptr)
return 2;
else
return 0;
}
}
}
}
template <typename T>
bool isRB(RBTreeNode<T>* root) //判断以root为根的二叉树是否为红黑树(已假定节点颜色不是为红色就是为黑色)
{
if (root->color == ColorFlag::RED)
{
cout << "根节点不为黑色,非红黑树" << endl;
return false;
}
struct memory
{
RBTreeNode<T>* p;
int direction;
T lmin;
memory(RBTreeNode<T>* p, int d) :p(p), direction(d) {}
};
T lmax;
T rmin;
T rmax;
int d = 0;
RBTreeNode<T>* ptr = root;
RBTreeNode<T>* const dest = ptr;
stack<memory> arrange;
bool TF = false;
int blacknum = 0; //统计路径上黑节点个数的变量
int preroadblacknum = 0; //当前路径的前一路径上黑节点数目
while (true)
{
if (Searchd(ptr, d) == 0)
{
if (ptr == dest)
{
if (d == 0)
return true;
}
if (d == 0)
{
if (arrange.top().p != dest)
{
if (ptr->color == ColorFlag::RED && arrange.top().p->color == ColorFlag::RED)
{
cout << "在根节点到外节点的路径上存在两个连续红色节点,非红黑树" << endl;
return false;
}
}
addBlackNum(ptr, blacknum);
if (examineBlackHeight(TF, preroadblacknum, blacknum) == false)
return false;
if (arrange.top().direction == 1)
{
arrange.top().lmin = ptr->data;
lmax = ptr->data;
}
else
{
rmin = ptr->data;
rmax = ptr->data;
}
}
else
{
if (d == 1)
{
if (lmax >= ptr->data)
{
cout << "当前树非二叉搜索树,也非红黑树" << endl;
return false;
}
if (ptr == dest)
return true;
T lmin = arrange.top().lmin;
arrange.pop();
if (arrange.top().direction == 1)
{
arrange.top().lmin = lmin;
lmax = ptr->data;
}
else
{
rmin = lmin;
rmax = ptr->data;
}
}
else
{
if (rmin <= ptr->data)
{
cout << "当前树非二叉搜索树,也非红黑树" << endl;
return false;
}
if (ptr == dest)
return true;
if (ptr->left == nullptr)
{
arrange.pop();
if (arrange.top().direction == 1)
{
arrange.top().lmin = ptr->data;
lmax = rmax;
}
else
rmin = ptr->data;
}
else
{
T lmin = arrange.top().lmin;
arrange.pop();
if (arrange.top().direction == 1)
{
arrange.top().lmin = lmin;
lmax = rmax;
}
else
rmin = lmin;
}
}
}
reduceBlackNum(ptr, blacknum);
ptr = arrange.top().p;
d = arrange.top().direction;
}
else
{
RBTreeNode<T>* interval = nullptr;
if (d == 0)
{
if (arrange.empty() == false && arrange.top().p != dest)
{
if (ptr->color == ColorFlag::RED && arrange.top().p->color == ColorFlag::RED)
{
cout << "在根节点到外节点的路径上存在两个连续红色节点,非红黑树" << endl;
return false;
}
}
addBlackNum(ptr, blacknum);
if (ptr->left == nullptr || ptr->right == nullptr)
{
if (examineBlackHeight(TF, preroadblacknum, blacknum) == false)
return false;
}
arrange.push(memory(ptr, Searchd(ptr, d)));
if (arrange.top().direction == 1)
ptr = ptr->left;
else
ptr = ptr->right;
}
else
{
if (ptr->data <= lmax)
{
cout << "当前树非二叉搜索树,也非红黑树" << endl;
return false;
}
arrange.top().direction = 2;
ptr = ptr->right;
}
d = 0;
}
}
}
template <typename T>
void linkWithUpper(RBTreeNode<T>* parent, RBTreeNode<T>* original, RBTreeNode<T>* _new)
{
if (original == parent->left)
{
parent->left = _new;
}
else
{
parent->right = _new;
}
}
template <typename T>
RBTreeNode<T>* InsertRB(RBTreeNode<T>* root, T key)
{
//红黑树插入
if (root == nullptr)
return new RBTreeNode<T>(key, ColorFlag::BLACK);
else
{
stack<RBTreeNode<T>*> stackforflashback;
RBTreeNode<T>* p = root;
while (p != nullptr) //搜索插入位置
{
stackforflashback.push(p);
if (key < p->data)
p = p->left;
else if (key > p->data)
p = p->right;
else
{
cout << "要插入的关键字在AVL树中已存在,插入失败" << endl;
return nullptr;
}
}
if (key < stackforflashback.top()->data)
{
p = stackforflashback.top()->left = new RBTreeNode<T>(key, ColorFlag::RED);
}
else
{
p = stackforflashback.top()->right = new RBTreeNode<T>(key, ColorFlag::RED);
}
enum class condition_be_processed { L1, L2, L3, _L1, _L2, _L3 }distinguish;
RBTreeNode<T>* q = nullptr;
RBTreeNode<T>* g = nullptr;
while (stackforflashback.empty() == false) //从第一棵满足循环不变条件的子树(就是新插入的节点)开始逐步向上调整颜色或进行平衡化旋转,直到原红黑树重新恢复平衡为止
{
if (g != nullptr)
{
if (g->color == ColorFlag::BLACK)
{
linkWithUpper(stackforflashback.top(), p, g);
return root;
}
else
p = g;
}
q = stackforflashback.top(); //进入新一轮循环后p为满足循环不变条件的子树的根节点,stackforflashback栈顶指针为其父节点指针
stackforflashback.pop();
if (q->color == ColorFlag::BLACK)
return root;
g = stackforflashback.top();
stackforflashback.pop();
if (q == g->left)
{
if (g->right != nullptr && g->right->color == ColorFlag::RED)
distinguish = condition_be_processed::L1;
else if (p == q->left)
distinguish = condition_be_processed::L2;
else
distinguish = condition_be_processed::L3;
}
else if (g->left != nullptr && g->left->color == ColorFlag::RED)
distinguish = condition_be_processed::_L1;
else if (p == q->left)
distinguish = condition_be_processed::_L2;
else
distinguish = condition_be_processed::_L3;
g->color = ColorFlag::RED;
if (distinguish == condition_be_processed::L1 || distinguish == condition_be_processed::_L1)
{
q->color = ColorFlag::BLACK;
if (distinguish == condition_be_processed::L1)
g->right->color = ColorFlag::BLACK;
else
g->left->color = ColorFlag::BLACK;
}
else if (distinguish == condition_be_processed::L2 || distinguish == condition_be_processed::_L3)
{
q->color = ColorFlag::BLACK;
p = g;
if (distinguish == condition_be_processed::L2)
RotateR(g);
else
RotateL(g);
}
else if (distinguish == condition_be_processed::_L2 || distinguish == condition_be_processed::L3)
{
p->color = ColorFlag::BLACK;
p = g;
if (distinguish == condition_be_processed::_L2)
RotateRL(g);
else
RotateLR(g);
}
}
g->color = ColorFlag::BLACK;
return g;
}
}