本人在网上找了很久 2-3-4 树的实例,但是少之又少,而且没有注释,所以,我总结了一下 2-3-4 树的 实例。
这是用C++ 写的
先定义一个Node类
//bstree.h
#include <iostream>
#include <vector>
#include <map>
#define TWO_LINK 2 //表明是一个2-节点
#define THREE_LINK 3
#define FOUR_LINK 4
using namespace std;
class Node
{
protected:
int key[3]; //这是为了存键的最大空间准备的, 可以存放三个值,就相当于一个4-节点,
//但是 可以用来存储2- 、 3-节点
string value[3]; //同理,这是用来存值的
vector<Node*> node_list; //对应于一个节点的四条子链接,可以只用两条三条
public:
bool put(Node** node, int key, string value); //放值进去
string search_node(Node* node, int key); //以key来查找value
Node();
Node(int key, string value); //两个构造函数
~Node(); //析构函数
private:
int flag_node; //标志位,区分是什么类型的节点
string search_two(Node* node, int key); //在2-节点中查找
string search_three(Node *node, int key); //在3-节点中查找
Node* deal_links(Node** child, Node **now, int key, string value, int depth); //处理3-节点变成4-节点的问题
void add_second_node(Node** now, int key, string value); //加入2-节点
void add_third_node(Node** now, int key, string value); //加入3-节点
Node* deal_four_links(Node** child, Node** now); //将4-节点转换为正常节点
void deal_top_tree(Node** now); //如果root根是4-节点的处理
Node* put_node(Node** node, int key, string value, int depth); //将节点放进去
Node* put_two(Node** node, int key, string value, int depth); //将节点放进2-节点
Node* put_three(Node** node, int key, string value, int depth); //将节点放进3-节点
};
//bstree.cpp
#include <iostream>
#include "2-3tree.h"
using namespace std;
Node::Node() //无参构造函数
{
node_list.resize(4); //初始化一个vector vector 是一个 键值对
this->flag_node = TWO_LINK;
this->key[0] = 0;
this->value[0] = "";
vector<Node*>::iterator iter; //迭代器
for(iter = node_list.begin(); iter != node_list.end(); iter++)
(*iter) = NULL;
}
Node::Node(int key, string value)
{
node_list.resize(4);
this->flag_node = TWO_LINK;
this->key[0] = key;
this->value[0] = value;
vector<Node*>::iterator iter; //迭代器
for(iter = node_list.begin(); iter != node_list.end(); iter++)
(*iter) = NULL;
}
Node::~Node() //析构函数
{
}
bool Node::put(Node** node, int key, string value) //放置节点 进树
{
if(put_node(node, key, value, 0) != NULL)
return true;
else
return false;
}
Node* Node::put_node(Node** node, int key, string value, int depth)
{
Node* child_node;
if((*node) == NULL)
return NULL;
switch((*node)->flag_node)
{
case TWO_LINK:
child_node = Node::put_two(node, key, value, depth + 1);
break;
case THREE_LINK:
child_node = Node::put_three(node, key, value, depth + 1);
break;
default:
return NULL;
}
return Node::deal_links(&child_node, node, key, value, depth);
}
Node* Node::put_two(Node** node, int key, string value, int depth)
{
int cmp = key - (*node)->key[0];
if(cmp > 0)
{
return Node::put_node(&((*node)->node_list[1]), key, value, depth);
}
else if(cmp < 0)
{
return Node::put_node(&((*node)->node_list[0]), key, value, depth);
} else {
(*node)->value[0] = value;
}
return *node;
}
Node* Node::put_three(Node** node, int key, string value, int depth)
{
if (key <= (*node)->key[0])
{
return Node::put_node(&((*node)->node_list[0]), key, value, depth);
}
else if (key > (*node)->key[0] && key <= (*node)->key[1])
{
return Node::put_node(&((*node)->node_list[1]), key, value, depth);
}
else if(key > (*node)->key[1])
{
return Node::put_node(&((*node)->node_list[2]), key, value, depth);
}
else return NULL;
}
Node* Node::deal_links(Node** child, Node** now, int key, string value, int depth)
{
if(*child == NULL)
{
switch((*now)->flag_node)
{
case TWO_LINK:
add_second_node(now, key, value);
break;
case THREE_LINK:
add_third_node(now, key, value);
break;
default:
return NULL;
}
if(depth == 0 && (*now)->flag_node == FOUR_LINK)
deal_top_tree(now);
return (*now);
}
if((*child)->flag_node == FOUR_LINK)
deal_four_links(child, now);
if(depth == 0 && (*now)->flag_node == FOUR_LINK)
deal_top_tree(now);
return (*now);
}
void Node::deal_top_tree(Node** now) //头节点的分裂函数
{
Node* root = new Node((*now)->key[1], (*now)->value[1]);
Node* child_left = new Node((*now)->key[0], (*now)->value[0]);
Node* child_right = new Node((*now)->key[2], (*now)->value[2]);
child_left->node_list[0] = (*now)->node_list[0];
child_left->node_list[1] = (*now)->node_list[1];
child_right->node_list[0] = (*now)->node_list[2];
child_right->node_list[1] = (*now)->node_list[3];
root->node_list[0] = child_left;
root->node_list[1] = child_right;
(*now) = root;
}
void Node::add_second_node(Node** now, int key, string value)
{
(*now)->flag_node = THREE_LINK;
if (key < (*now)->key[0])
{
(*now)->key[1] = (*now)->key[0];
(*now)->value[1] = (*now)->value[0];
}
int location = (key > (*now)->key[0]) ? 1 : 0;
(*now)->key[location] = key;
(*now)->value[location] = value;
}
void Node::add_third_node(Node** now, int key, string value)
{
(*now)->flag_node = FOUR_LINK;
if (key < (*now)->key[0])
{
(*now)->key[2] = (*now)->key[1];
(*now)->value[2] = (*now)->value[1];
(*now)->key[1] = (*now)->key[0];
(*now)->value[1] = (*now)->key[0];
(*now)->key[0] = key;
(*now)->value[0] = value;
}
else if (key < (*now)->key[1] && key > (*now)->key[0])
{
(*now)->key[2] = (*now)->key[1];
(*now)->value[2] = (*now)->value[1];
(*now)->key[1] = key;
(*now)->value[1] = value;
}
else if (key > (*now)->key[1])
{
(*now)->key[2] = key;
(*now)->value[2] = value;
}
else if (key == (*now)->key[0])
{
(*now)->flag_node = THREE_LINK;
(*now)->value[0] = value;
}
else if (key == (*now)->key[1])
{
(*now)->flag_node = THREE_LINK;
(*now)->value[1] = value;
}
}
Node* Node::deal_four_links(Node** child, Node** now) //4-节点的分裂函数
{
if ((*now)->flag_node == TWO_LINK)
{
add_second_node(now, (*child)->key[1], (*child)->value[1]);
}
else if ((*now)->flag_node == THREE_LINK)
{
add_third_node(now, (*child)->key[1], (*child)->value[1]);
}
Node* child_left = new Node((*child)->key[0], (*child)->value[0]);
Node* child_right = new Node((*child)->key[2], (*child)->value[2]);
child_left->node_list[0] = (*child)->node_list[0];
child_left->node_list[1] = (*child)->node_list[1];
child_right->node_list[0] = (*child)->node_list[2];
child_right->node_list[1] = (*child)->node_list[3];
if ((*child) == (*now)->node_list[0])
{
(*now)->node_list[3] = (*now)->node_list[2];
(*now)->node_list[2] = (*now)->node_list[1];
(*now)->node_list[0] = child_left;
(*now)->node_list[1] = child_right;
}
else if ((*child) == (*now)->node_list[1])
{
(*now)->node_list[3] = (*now)->node_list[2];
(*now)->node_list[1] = child_left;
(*now)->node_list[2] = child_right;
}
else if ((*child) == (*now)->node_list[2])
{
(*now)->node_list[2] = child_left;
(*now)->node_list[3] = child_right;
}
delete (*child);
return (*now);
}
string Node::search_node(Node* node, int key)
{
switch (node->flag_node)
{
case TWO_LINK:
return Node::search_two(node, key);
case THREE_LINK:
return Node::search_three(node, key);
default :
return NULL;
}
}
string Node::search_two(Node* node, int key)
{
int cmp = key - node->key[0];
if (cmp > 0)
{
return Node::search_node(node->node_list[1], key);
}
else if (cmp < 0)
{
return Node::search_node(node->node_list[0], key);
}
else
{
return node->value[0];
}
}
string Node::search_three(Node* node, int key)
{
if (key < node->key[0])
{
return Node::search_node(node->node_list[0], key);
}
else if (key > node->key[0] && key < node->key[1])
{
return Node::search_node(node->node_list[1], key);
}
else if(key > node->key[1])
{
return Node::search_node(node->node_list[2], key);
}
else if (key == node->key[0])
{
return node->value[0];
}
else if (key == node->key[1])
{
return node->value[1];
}
else return NULL;
}
int main() // 验证函数
{
Node* root = new Node(8, "root");
char ch[10][2] = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
int random;
for(int i = 1; i <= 10; i++)
{
random = i + 2;
root->put(&root, random, (string)ch[i - 1]);
}
for(int i = 1; i <= 10; i++)
{
random = i + 2;
cout << root->search_node(root, random) << " ";
}
char c;
cin >> c;
return 0;
}

运行后效果如下
浙公网安备 33010602011771号