本人在网上找了很久 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;
}
 


运行后效果如下