数据结构-----------B树
来源:互联网 发布:ubuntu创建用户和目录 编辑:程序博客网 时间:2024/05/10 18:56
一、B 树(平衡的多叉树)
一棵M阶(M>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树,它的性质为:
1、根节点至少有两个孩子
2、每个非根节点有[⌈M/2⌉,M]个孩子;⌈M/2⌉向上取整
3、每个非根节点有[⌈M/2⌉-1,M-1]个关键字,并且以升序排列
4、key[i]和key[i+1]之间的孩子节点的值介于key[i]、key[i+1]之间‘
5、所有的叶子节点都在同一层。
二、基本操作
(1)查找
(2)中序遍历
(3)插入
三、代码实现:
#pragma once#include<iostream>#include<utility>using namespace std;template<class K,int M>struct BTreeNode{BTreeNode():_parent(NULL),_size(0){for(int i=0;i<M+1;i++){_subs[i]=NULL;}}K _keys[M];BTreeNode<K,M>* _subs[M+1];BTreeNode<K,M>* _parent;size_t _size;};template<class K,int M>class BTree{public:typedef BTreeNode<K,M> Node;BTree():_root(NULL){}Node* Find(K key) //查找key存在位置{if(_root==NULL){return NULL;}Node* cur=_root;Node* parent=NULL; int end=cur->_size-1;while(cur){parent=cur;if(key>cur->_keys[end]){cur=cur->_subs[end+1];if(cur)end=cur->_size-1;}else if(key<cur->_keys[end]){if(end==0){cur=cur->_subs[end];if(cur)end=cur->_size-1;}elseend--;}else{return cur;}}return parent;}bool Insert(K key){if(_root==NULL){_root=new Node;_root->_keys[_root->_size]=key;_root->_size++;return true;}Node* cur=Find(key);while(1){ int end=cur->_size-1; for(size_t i=0;i<end+1;i++) //判断该节点是否存在该关键字(判断返回的是parent还是cur){if(cur->_keys[i]==key){return false;}}while(end>=0&&end<cur->_size) //插入关键字{ if(cur->_keys[end]>key) {cur->_keys[end+1]=cur->_keys[end]; } else {cur->_keys[end+1]=key;cur->_size++;break; } end--; if(end==-1) { cur->_keys[end+1]=key;cur->_size++;break; } }end=cur->_size-1;Node* parent=cur->_parent;int div=M/2;Node* tmp;if(cur->_size>=M) //分裂{int index=0;tmp=new Node;for(int i=div+1;i<cur->_size;i++) //从M/2处分裂,创建一个新的节点,把M/2后的关键字拷贝到tmp中{tmp->_keys[index++]=cur->_keys[i];tmp->_size++;}index=0;for(int i=div+1;i<cur->_size+1;i++) //从M/2处分裂,把M/2后的孩子拷贝到tmp中{tmp->_subs[index++]=cur->_subs[i];}if(parent!=NULL) //分裂的该节点不为根节点{int i=parent->_size;if(i==M-1) //如果分裂的该节点是parent->_subs[M-1],则不需拷贝前面的parent->_subs[i],直接把创建的tmp节点链在parent->_subs[i]后面{parent->_subs[i+1]=tmp;}else //如果分裂的该节点是parent->_subs[i],i<M-1,则需拷贝前面的parent->_subs[i],依次把parent的孩子指针向后移动,空出合适位置,链起tmp{while(parent->_subs[i]!=cur){parent->_subs[i+1]=parent->_subs[i];i--;}parent->_subs[i+1]=tmp;} tmp->_parent=parent;}else //分裂的该节点为根节点{ Node* root=new Node; root->_keys[0]=cur->_keys[div]; root->_subs[0]=cur; root->_subs[1]=tmp; cur->_parent=root; tmp->_parent=root; _root=root; _root->_size++;}}else{return true;}cur->_size=cur->_size-tmp->_size-1; //把cur->_keys[M/2]插入上层,进行循环int new_key=cur->_keys[div];cur=cur->_parent;key=new_key;}} void InOrder(){_InOrder(_root);}private:void _InOrder(Node* root){if(root==NULL){return;}int i=0;for(;i<root->_size;i++){_InOrder(root->_subs[i]);cout<<root->_keys[i]<<"->";}_InOrder(root->_subs[i]);}private:Node* _root;};
#include "BTree.h"int main(){BTree<int,3> b1;BTree<int,4> b2;BTree<int,5> b3;int a[]={53,75,139,49,145,36,101,36,24,56};for(int i=0;i<sizeof(a)/sizeof(a[0]);i++){b1.Insert(a[i]);}for(int i=0;i<sizeof(a)/sizeof(a[0]);i++){b2.Insert(a[i]);}for(int i=0;i<sizeof(a)/sizeof(a[0]);i++){b3.Insert(a[i]);}cout<<"三叉:";b1.InOrder();cout<<endl;cout<<"四叉:";b2.InOrder();cout<<endl;cout<<"五叉:";b3.InOrder();cout<<endl;system("pause");return 0;}四、结果:
0 0
- 【数据结构】B树/B+树
- 数据结构--B 树、B+ 树、B* 树
- 数据结构:B树&B+树&B*树
- 数据结构--B树
- 经典数据结构B+树
- 数据结构B-树
- 【数据结构】B树_BTree
- 数据结构B树
- 数据结构-B树实现
- 数据结构之B树
- B+树数据结构
- 高级数据结构B树
- 数据结构-----------B树
- 【数据结构】浅析B树
- 数据结构之B-树
- java数据结构----B树
- 算法数据结构-B树
- 数据结构:B-树
- 适配ios7的时候仿UIAlertView弹框效果,修改内部的label和button的属性
- Elasticsearch在生产环境中的优化
- springMVC和Shiro框架整合使用简单示例
- 下载地址
- margin之百分比
- 数据结构-----------B树
- C语言中的单引号和双引号的区别
- hdu5735Born Slippy
- x86_64下多平台编译qt4.8.6
- TIANKENG’s restaurant 【区间覆盖 好题】
- 打印两个有序链表的公共部分
- 成为Java高手的25个学习要点
- UVA 10615 Rooks <二分图 + 正则二分图 + 完全匹配>
- Android之使用URLConnection进行网络编程