亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

平衡搜索樹之B-樹

發布時間:2020-07-22 10:13:51 來源:網絡 閱讀:631 作者:小伙真倔啊 欄目:編程語言

B-樹

    一種適合外查找的平衡多叉樹(有些地方寫的是B-樹,注意不要誤讀 成"B減樹") 。


M階的B樹滿足如下性質

    1、根節點至少有兩個孩子;

    2、每個非根節點有[[M/2],M]個孩子;

    3、每個非根節點有[[M/2],M-1]個關鍵字,并且以升序排列;

    4、key[i]和key[i+1]之間的孩子節點的值介于key[i]和key[i+1]之間;

    5、所有的葉子節點都在同一層。

M階的B樹----M=3

平衡搜索樹之B-樹

 插入

        如果插入值后,該節點的關鍵字的個數大于規定的要求,則需要調整,即分裂(新創建一個節點,把位于關鍵字序列中的中位數(不包含中位數)以后的值包括子樹都拷貝到新建的節點中,將中位數提出成樹的根節點,中位數以前的值將成為中位數的左子樹,后半部分成為右子樹),如下圖:平衡搜索樹之B-樹

應用:運用于數據庫和文件系統。


具體實現代碼如下:

#pragma once

//使用外查找的平衡多叉樹

//性質:

//    1、根節點至少有兩個孩子

//    2、每個非根節點有[[M/2],M]個孩子

//    3、每個非根節點有[[M/2],M-1]個關鍵字,并且以升序排列

//    4、key[i]和key[i+1]之間的孩子節點的值介于key[i]和key[i+1]之間

//    5、所有的葉子節點都在同一層


template<class K,int M>//B數一個節點的結構

struct BTreeNode

{

K _key[M];//關鍵字的個數為M-1,多留一個位置可以更加方便的求取中位數

BTreeNode<K,M>* _subs[M+1];//方便插入時分裂,子樹的最大個數為M個,關鍵字比他少一個

BTreeNode<K,M>* _parent;//指向父親節點

size_t _size;//數組中存放的有效關鍵字的個數

BTreeNode()

:_parent(NULL)

,_size(0)

{

for(int i = 0;i < M+1;++i)

{

_subs[i] = NULL;

}

}

};


template<class K,class V>//需要返回兩個參數,使用結構體

struct Pair

{

K _first;

V _second;


Pair(const K& key = K(),const V& value = V())//缺省參數,會調用默認構造函數

:_first(key)

,_second(value)

{ }

};


template<class K,int M>

class BTree

{

typedef BTreeNode<K,M> Node;

public:

BTree()

:_root(NULL)

{ }


Pair<Node*,int> Find(const K& key)//查找

{

if(_root == NULL)

return Pair<Node*,int>(NULL,-1);

Node* parent = NULL;

Node* cur = _root;

while (cur)

{

int index = 0;

while (index < cur->_size)

{

if(key == cur->_key[index])

{

return Pair<Node*,int>(cur,index);

}

else if(key < cur->_key[index])

{

break;

}

else

{

index++;

}

}

parent = cur;

cur = cur->_subs[index];

}

return Pair<Node* ,int>(parent,-1);

//找完也沒找到,為了使得該情況下方便插入節點,因此返回panrent,插入節點插入在parent上

}


bool Insert(const K& key)//插入

{

//當前無節點

if(_root == NULL)

{

_root = new Node;//開辟一個新的節點

_root->_key[0] = key;

_root->_subs[0] = NULL;

_root->_parent = NULL;

_root->_size++;

return true;

}


Pair<Node*,int> cur = Find(key);

if(cur._second != -1)//找到,則返回false,不插入重復關鍵字

{

return false;

}

//在節點cur中插入key和sub

Node* str = cur._first;

K newKey = key;

Node* sub = NULL;

while (1)

{

_InsertKey(str,newKey,sub);

if(str->_size < M)//關鍵字的數量小于M,則正確,直接返回

return true;


//插入數據后,該節點的關鍵字的個數大于規定的數量,需要調整,進行分裂

int mid = (str->_size - 1)/2;

int index = 0;

Node* temp = new Node;


//先拷貝下標為mid后的關鍵字

for(size_t i = mid + 1;i < str->_size;i++)

{

temp->_key[index++] = str->_key[i];

temp->_size++;

str->_key[i] = 0;

}


//接著拷貝下標為mid的關鍵字的sub

index = 0;

for(size_t i = mid + 1;i <= str->_size;i++)

{

temp->_subs[index++] = str->_subs[i];

if(str->_subs[i] != NULL)

str->_subs[i]->_parent = temp;

}

//更改str的大小

str->_size = (str->_size - 1)/2;

if(str->_parent == NULL)

{

_root = new Node;

_root->_key[0] = str->_key[mid];

str->_key[mid] = 0;

_root->_subs[0] = str;

_root->_subs[1] = temp;

_root->_size = 1;

str->_parent = _root;

temp->_parent = _root;

return true;

}

else

{

newKey = str->_key[mid];

str->_key[mid] = 0;

sub = temp;

str = str->_parent;

}

}

}


void InOrder()

{

_InOrder(_root);

cout<<endl;

}

protected:

void _InsertKey(Node* cur,const K& key,Node* sub)

{

int index = cur->_size - 1;

while (index >= 0 && cur->_key[index] > key)//若插入的節點比改位置的值小,則需要移位

{

cur->_key[index+1] = cur->_key[index];

cur->_subs[index+2] = cur->_subs[index+1];

--index;

}

//否則,直接插入

cur->_key[index + 1] = key;

cur->_subs[index+2] = sub;

if(sub != NULL)

sub->_parent = cur;

cur->_size++;

}


void _InOrder(Node* root)

{

if(root == NULL)

return;

for(int i = 0;i < root->_size;i++)

{

_InOrder(root->_subs[i]);

cout<<root->_key[i]<<" ";

}

_InOrder(root->_subs[root->_size]);

}

protected:

Node* _root;

};


void BTreeTest()

{

BTree<int,3> tree;

int a[] = {53,75,139,49,145,36,101};

for(int i = 0;i < sizeof(a)/sizeof(a[i]);i++)

{

tree.Insert(a[i]);

}

tree.InOrder();

}

運行結果:

平衡搜索樹之B-樹


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宜君县| 基隆市| 江陵县| 富源县| 镇宁| 瑞安市| 磴口县| 吉木萨尔县| 黔西县| 保靖县| 黔西| 海南省| 滦平县| 鹤壁市| 龙口市| 金阳县| 棋牌| 洛宁县| 宜兰市| 闵行区| 三穗县| 东阿县| 广饶县| 永州市| 封丘县| 泾川县| 峨边| 金沙县| 琼中| 康定县| 吉隆县| 双柏县| 呈贡县| 崇仁县| 安阳县| 临沂市| 开远市| 华容县| 塘沽区| 简阳市| 肥西县|