算法导论第十八章-B树-Cpp代码实现
2016-06-20 21:55
405 查看
B数的实现。删除有点复杂且没有伪代码,以后有时间再补上。
b_tree.h
#pragma once
/*************************************************
Author:董小歪
Date:2016-06-20
Description:算法导论第十八章-B树-Cpp代码实现
**************************************************/
#ifndef B_TREE_H
#define B_TREE_H
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define t 3 //最小度数
template <typename T>
struct BTreeNode
{
int n; //关键字数量
bool leaf; //是否为叶结点
vector<T> keys; //关键字
vector<BTreeNode<T>*> children; //孩子结点
public:
BTreeNode(bool _leaf = false):n(0), //关键字数量开始为0
leaf(_leaf), //初始化为叶子
keys(vector<T>(2*t-1)), //关键字最大个数
children(vector<BTreeNode<T>*>(2*t, nullptr)) //最多可以有的孩子数量
{}
};
template <typename T>
class BTree
{
public:
BTree(bool _leaf = true) { root = new BTreeNode<T>(); root->leaf = _leaf; }
typedef pair<BTreeNode<T>*, int> mypair; //定义搜索结果数据结构
mypair b_tree_search(T k); //搜索B树
void b_tree_insert(T k); //插入关键字
void b_tree_delete(T k);
inline BTreeNode<T>* get_root() { return root; } //得到树根
private:
void b_tree_split_child(BTreeNode<T>*x, int i); //分裂B树中的节点
void b_tree_insert_nonfull(BTreeNode<T>* x, T k); //插入非满的根结点为根的树中
mypair b_tree_search(BTreeNode<T>* x, T k); //搜索B树
BTreeNode<T>* root; //树根
};
template <typename T>
pair<BTreeNode<T>*, int> BTree<T>::b_tree_search(T k)
{
return b_tree_search(root, k);
}
template <typename T>
pair<BTreeNode<T>*, int> BTree<T>::b_tree_search(BTreeNode<T>* x, T k)
{
int i = 1;
while (i <= x->n && k > x->keys[i - 1])
++i;
if (i <= x->n && k == x->keys[i - 1])
return make_pair(x, i - 1);
else if (x->leaf) //如果是叶节点
return make_pair(nullptr, 0);
else
return b_tree_search(x->children[i - 1], k);
}
template <typename T>
void BTree<T>::b_tree_split_child(BTreeNode<T>*x, int i)
{
BTreeNode<T>* z = new BTreeNode<T>();
BTreeNode<T>* y = x->children[i];
z->leaf = y->leaf;
z->n = t - 1;
//************1.建立新结点z************
for (int j = 0; j <= t - 2; ++j)
z->keys[j] = y->keys[t + j];
if (!y->leaf)
for (int j = 0; j <= t - 1; ++j)
z->children[j] = y->children[t + j];
//************2.修改y的关键字数量************
y->n = t - 1;
//************3.增加x结点的关键字和孩子************
for (int j = x->n; j >= i + 1; --j)
x->children[j + 1] = x->children[j];
x->children[i + 1] = z;
for (int j = x->n; j >= i + 1; --j)
x->keys[j] = x->keys[j - 1];
x->keys[i] = y->keys[t - 1];
x->n = x->n + 1;
}
template <typename T>
void BTree<T>::b_tree_insert(T k)
{
BTreeNode<T>* r = root;
if (r->n == 2 * t - 1)
{
BTreeNode<T>* s = new BTreeNode<T>();
root = s;
s->children[0] = r;
b_tree_split_child(s, 0);
b_tree_insert_nonfull(s, k);
}
else
b_tree_insert_nonfull(r, k);
}
template <typename T>
void BTree<T>::b_tree_insert_nonfull(BTreeNode<T>* x, T k)
{
int i = x->n;
if (x->leaf)
{
while (i >= 1 && k < x->keys[i - 1])
{
x->keys[i] = x->keys[i - 1];
--i;
}
x->keys[i] = k;
x->n = x->n + 1;
}
else
{
while (i >= 1 && k < x->keys[i - 1])
--i;
++i;
if (x->children[i - 1]->n == 2 * t - 1)
{
b_tree_split_child(x, i - 1);
if (k > x->keys[i - 1])
++i;
}
b_tree_insert_nonfull(x->children[i - 1], k);
}
}
template <typename T>
void BTree<T>::b_tree_delete(T k)
{
}
#endif // !B_TREE_H
测试代码:
main_entrance.cpp
#include "b_tree.h"
int main()
{
BTree<char> btree;
btree.b_tree_insert('G');
btree.b_tree_insert('M');
btree.b_tree_insert('P');
btree.b_tree_insert('X');
BTreeNode<char>* c0 = new BTreeNode<char>(true);
BTreeNode<char>* c1 = new BTreeNode<char>(true);
BTreeNode<char>* c2 = new BTreeNode<char>(true);
BTreeNode<char>* c3 = new BTreeNode<char>(true);
BTreeNode<char>* c4 = new BTreeNode<char>(true);
c0->n = 4; c0->keys[0] = 'A'; c0->keys[1] = 'C'; c0->keys[2] = 'D'; c0->keys[3] = 'E';
c1->n = 2; c1->keys[0] = 'J'; c1->keys[1] = 'K';
c2->n = 2; c2->keys[0] = 'N'; c2->keys[1] = 'O';
c3->n = 5; c3->keys[0] = 'R'; c3->keys[1] = 'S'; c3->keys[2] = 'T'; c3->keys[3] = 'U'; c3->keys[4] = 'V';
c4->n = 2; c4->keys[0] = 'Y'; c4->keys[1] = 'Z';
btree.get_root()->children[0] = c0;
btree.get_root()->children[1] = c1;
btree.get_root()->children[2] = c2;
btree.get_root()->children[3] = c3;
btree.get_root()->children[4] = c4;
btree.get_root()->leaf = false;
btree.b_tree_insert('B');
btree.b_tree_insert('Q');
btree.b_tree_insert('L');
btree.b_tree_insert('F');
system("pause");
}
没有测试结果。
b_tree.h
#pragma once
/*************************************************
Author:董小歪
Date:2016-06-20
Description:算法导论第十八章-B树-Cpp代码实现
**************************************************/
#ifndef B_TREE_H
#define B_TREE_H
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define t 3 //最小度数
template <typename T>
struct BTreeNode
{
int n; //关键字数量
bool leaf; //是否为叶结点
vector<T> keys; //关键字
vector<BTreeNode<T>*> children; //孩子结点
public:
BTreeNode(bool _leaf = false):n(0), //关键字数量开始为0
leaf(_leaf), //初始化为叶子
keys(vector<T>(2*t-1)), //关键字最大个数
children(vector<BTreeNode<T>*>(2*t, nullptr)) //最多可以有的孩子数量
{}
};
template <typename T>
class BTree
{
public:
BTree(bool _leaf = true) { root = new BTreeNode<T>(); root->leaf = _leaf; }
typedef pair<BTreeNode<T>*, int> mypair; //定义搜索结果数据结构
mypair b_tree_search(T k); //搜索B树
void b_tree_insert(T k); //插入关键字
void b_tree_delete(T k);
inline BTreeNode<T>* get_root() { return root; } //得到树根
private:
void b_tree_split_child(BTreeNode<T>*x, int i); //分裂B树中的节点
void b_tree_insert_nonfull(BTreeNode<T>* x, T k); //插入非满的根结点为根的树中
mypair b_tree_search(BTreeNode<T>* x, T k); //搜索B树
BTreeNode<T>* root; //树根
};
template <typename T>
pair<BTreeNode<T>*, int> BTree<T>::b_tree_search(T k)
{
return b_tree_search(root, k);
}
template <typename T>
pair<BTreeNode<T>*, int> BTree<T>::b_tree_search(BTreeNode<T>* x, T k)
{
int i = 1;
while (i <= x->n && k > x->keys[i - 1])
++i;
if (i <= x->n && k == x->keys[i - 1])
return make_pair(x, i - 1);
else if (x->leaf) //如果是叶节点
return make_pair(nullptr, 0);
else
return b_tree_search(x->children[i - 1], k);
}
template <typename T>
void BTree<T>::b_tree_split_child(BTreeNode<T>*x, int i)
{
BTreeNode<T>* z = new BTreeNode<T>();
BTreeNode<T>* y = x->children[i];
z->leaf = y->leaf;
z->n = t - 1;
//************1.建立新结点z************
for (int j = 0; j <= t - 2; ++j)
z->keys[j] = y->keys[t + j];
if (!y->leaf)
for (int j = 0; j <= t - 1; ++j)
z->children[j] = y->children[t + j];
//************2.修改y的关键字数量************
y->n = t - 1;
//************3.增加x结点的关键字和孩子************
for (int j = x->n; j >= i + 1; --j)
x->children[j + 1] = x->children[j];
x->children[i + 1] = z;
for (int j = x->n; j >= i + 1; --j)
x->keys[j] = x->keys[j - 1];
x->keys[i] = y->keys[t - 1];
x->n = x->n + 1;
}
template <typename T>
void BTree<T>::b_tree_insert(T k)
{
BTreeNode<T>* r = root;
if (r->n == 2 * t - 1)
{
BTreeNode<T>* s = new BTreeNode<T>();
root = s;
s->children[0] = r;
b_tree_split_child(s, 0);
b_tree_insert_nonfull(s, k);
}
else
b_tree_insert_nonfull(r, k);
}
template <typename T>
void BTree<T>::b_tree_insert_nonfull(BTreeNode<T>* x, T k)
{
int i = x->n;
if (x->leaf)
{
while (i >= 1 && k < x->keys[i - 1])
{
x->keys[i] = x->keys[i - 1];
--i;
}
x->keys[i] = k;
x->n = x->n + 1;
}
else
{
while (i >= 1 && k < x->keys[i - 1])
--i;
++i;
if (x->children[i - 1]->n == 2 * t - 1)
{
b_tree_split_child(x, i - 1);
if (k > x->keys[i - 1])
++i;
}
b_tree_insert_nonfull(x->children[i - 1], k);
}
}
template <typename T>
void BTree<T>::b_tree_delete(T k)
{
}
#endif // !B_TREE_H
测试代码:
main_entrance.cpp
#include "b_tree.h"
int main()
{
BTree<char> btree;
btree.b_tree_insert('G');
btree.b_tree_insert('M');
btree.b_tree_insert('P');
btree.b_tree_insert('X');
BTreeNode<char>* c0 = new BTreeNode<char>(true);
BTreeNode<char>* c1 = new BTreeNode<char>(true);
BTreeNode<char>* c2 = new BTreeNode<char>(true);
BTreeNode<char>* c3 = new BTreeNode<char>(true);
BTreeNode<char>* c4 = new BTreeNode<char>(true);
c0->n = 4; c0->keys[0] = 'A'; c0->keys[1] = 'C'; c0->keys[2] = 'D'; c0->keys[3] = 'E';
c1->n = 2; c1->keys[0] = 'J'; c1->keys[1] = 'K';
c2->n = 2; c2->keys[0] = 'N'; c2->keys[1] = 'O';
c3->n = 5; c3->keys[0] = 'R'; c3->keys[1] = 'S'; c3->keys[2] = 'T'; c3->keys[3] = 'U'; c3->keys[4] = 'V';
c4->n = 2; c4->keys[0] = 'Y'; c4->keys[1] = 'Z';
btree.get_root()->children[0] = c0;
btree.get_root()->children[1] = c1;
btree.get_root()->children[2] = c2;
btree.get_root()->children[3] = c3;
btree.get_root()->children[4] = c4;
btree.get_root()->leaf = false;
btree.b_tree_insert('B');
btree.b_tree_insert('Q');
btree.b_tree_insert('L');
btree.b_tree_insert('F');
system("pause");
}
没有测试结果。
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)