-
Notifications
You must be signed in to change notification settings - Fork 0
/
BTree.cpp
151 lines (139 loc) · 4.22 KB
/
BTree.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//
// Btree.cpp
// CS130A Final Project
//
// Created by Vikram Sastry on 3/6/16.
// Copyright © 2016 Vikram Sastry and Thien Hoang. All rights reserved.
//
#include "BTree.h"
#include "Constants.h"
#include <string>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
BTree::BTree(){
//Default Constructor
root = new BTreeNode(LEAF);
}
void BTree::insert(BTreeNode::DataType data){
//ALWAYS INSERT AT LEAF
BTreeNode* leaf = this->findNode(root, data.name);
leaf->insertSortLeaf(data);
this->AdjustingRoot(this->root);
}
void BTree::AdjustingRoot(BTreeNode* leaf) {
//ADJUSTING ROOT SO IT POINTS AT THE RIGHT PLACE
if (leaf->Parent == NULL){
this->root = leaf;
}
else {
this->AdjustingRoot(leaf->Parent);
}
}
BTreeNode *BTree::findNode(BTreeNode *root, string name) {
//FIND THE LEAVE CONTAINING NAME
if (root == NULL) {
cout <<"EMPTY TREE" <<endl;
root = new BTreeNode(LEAF);
return root;
}
if (root->isLeaf) {
return root;
}
if (!root->isLeaf) {//looking at the root or the internal node
for (int i = 0; i <= root->occupied; i++) {
if (root->DataArray[i].index == EMPTY || name < root->DataArray[i].name) {
//If we go pass the last entry or find an entry larger than what we're looking for
return findNode(root->PointerArray[i], name);
}
}
}
return NULL;
}
void BTree::printRange(string lowbound, string upbound) {
vector<BTreeNode::DataType> result = this->RangeQuery(this->root, lowbound, upbound);
for (int i = 0; i < result.size(); i++)
cout << "Name: " << result.at(i).name << " Index: " << result.at(i).index<< endl;
}
void BTree::printTree(BTreeNode *root) {
cout << root->toString() << endl;
if (root->isLeaf)
return;
else {
for (int i = 0; i <= root->occupied; i++) {
printTree(root->PointerArray[i]);
}
return;
}
}
void BTree::printLeaves(BTreeNode* root) {
if(!root->isLeaf)
printLeaves(root->PointerArray[0]);
else {
cout << root->toString() << endl;
if (root->PointerArray[M] != NULL)
printLeaves(root->PointerArray[M]);
return;
}
return;
}
vector<BTreeNode::DataType> BTree::RangeQuery(BTreeNode *root, string lowbound, string upbound) {
/*We will find the lower bound in the leaf and start collecting Data from one leaf to
another until we hit the upper bound*/
vector<BTreeNode::DataType> result;
if (root == NULL) {
cout << "We can't find it" << endl;
return result;
}
if (!root->isLeaf) {// looking at root or internal
for (int i = 0; i <= root->occupied; i++) {
if (root->DataArray[i].index == EMPTY || lowbound < root->DataArray[i].name) {
//If we go pass the last entry or find an entry larger than the lower bound
return RangeQuery(root->PointerArray[i], lowbound, upbound);
}
}
}
if (root->isLeaf) {
int j;
for (j = 0; j <= root->occupied; j++) {
if (root->DataArray[j].index == EMPTY || lowbound.compare(root->DataArray[j].name) <= 0) {
//We simply find the element larger than the lowerbound
break;
}
}
while (root->DataArray[j].name <= upbound) { // while we haven't exceeded the upperbound
if (root->DataArray[j].index != EMPTY){
result.push_back(root->DataArray[j]);
//cout << root->DataArray[j].name << ", ";
}
if (j >= root->occupied - 1) {//last node or empty node
if (root->PointerArray[M] != NULL) {//as long as next leaf is not NULL
root = root->PointerArray[M];
j = 0;
continue;
}
else {//if next leaf is NULL
//cout << "Do not exceed upperbound" << endl;
return result;
}
}
j++;
}
cout <<endl;
}
return result;
}
void BTree::remove(string name) {
//DELETE AT LEAF
BTreeNode* leaf = findNode(root, name);
if(leaf->find(name,EXACT)==NOTFOUND){
cout << "TARGET NOT FOUND" << endl;
return;
}
cout << "Found TARGET. Now deleting it. "<< endl;
leaf=leaf->remove(name);
cout << "DELETE SUCESSFULLY. Now ADJUSTING ROOT" <<endl;
AdjustingRoot(leaf);
}