每个节点都是一个结构体, 由Key-Value 一对
规定:
1,左子树的所有节点的 key 小于根节点的key
2,右子树的所有节点的 key 大于根节点的key
在这两个规定下就可以构建一棵二查搜索树
简单用c++的一个类来构建一棵二叉搜索树
实现功能
统计圣经里面所有单词的词频,把单词存入Key中,在value中记录单词出现的次数
- size();返回节点数量
- isEmpth();返回树是否为空
- insetr();插入一个节点(单词),或者更新单词的数量也就是value的值++
- contain();是否有这个key存在
- searck();返回key对应的value
- minimun();返回Key的最小值
- maxmnm();返回key的最大值
- perOeder();前序遍历
- inOrder();终须遍历
- PostOrder();后序遍历
- afterlOrder();广都遍历
- remoceMax()删除key最大的值
- removeMin()删除后Key最小的值
- remove() 删除给定的Key值
- 还有四个方法没事实现等以后了在说
template < typename Key, typename Value >
class BST2
{
struct Node
{
Key key;
Value value;
Node *left;
Node *right;
int count;
Node(Key key,Value value){
this->key = key;
this->value = value;
this->count = 1;
this->left = this->right = NULL;
}
Node(Node *node)
{
this->key =node->key;
this->value =node->value;
this->count = node->count;
this->left = node->left;
this->right = node->right;
}
};
Node *root;
int count=0;
public:
BST2() {};
~BST2() {};
int size() { return count; }
bool isEmpth() { return count == 0 ? false : true; }
//插入节点
void insert(Key key, Value value)
{
root = insert(root, key, value);
}
Node *insert(Node* node, Key key, Value value)
{
if (node == NULL)
{
count++;
return node = new Node(key, value);
}
node->count++;
if (key == node->key)
{
node->value = node->value + 1;
count--;
return node;
}
if (key < node->key)
//insert(node->left, key, value);
node->left = insert(node->left, key, value);
else
//insert(node->right, key, value);
node->right = insert(node->right, key, value);
return node;
}
//是否有这个节点
bool contain(Key key)
{
if (root == NULL) return false;
else return contain(root,key);
}
bool contain(Node* node, Key key)
{
if (node == NULL) return false;
if (node->key == key)
return true;
if (key < node->key)
return contain(node->left, key);
else
return contain(node->right, key);
}
//返回查找的Key对应的value
Value* search(Key key)
{
if (contain(key) == true)
return search(root, key);
else return NULL;
}
Value* search(Node* node, Key key)
{
if (key == node->key)
return &(node->value);
if (key > node->key)
return search(node->right, key);
else
return search(node->left, key);
}
//返回最小值最大值
Node* minimum()
{
if (root != NULL)
return minimum(root);
else
return NULL;
}
Node* minimum(Node* node)
{
if (node->left != NULL)
return minimum(node->left);
else
return node;
}
Node* maximnm()
{
if (root != NULL)
return minimum(root);
else
return NULL;
}
Node* maximnm(Node* node)
{
if (node->right != NULL)
return minimum(node->right);
else
return node;
}
//四种遍历 前中后深度遍历 后序遍历
void preOrder()
{
if (root) preOrder(root);
}
void preOrder(Node *node)
{
cout << node->key << " " << node->value << " " << node->count << endl;
if (node->left != NULL)
preOrder(node->left);
if (node->right != NULL)
preOrder(node->right);
}
void inOrder()
{
if (root) inOrder(root);
}
void inOrder(Node *node)
{
if (node->left != NULL)
inOrder(node->left);
cout << node->key << " " << node->value << " " << node->count << endl;
if (node->right != NULL)
inOrder(node->right);
}
void postOrder()
{
if (root) postOrder(root);
}
void postOrder(Node *node)
{
if(node->left != NULL)
postOrder(node->left);
if(node->right !=NULL)
postOrder(node->right);
cout << node->key << " " << node->value<<" "<<node->count << endl;
}
void afterlOrder()
{
if (root == NULL) return;
Node* n;
queue<Node* > q;
q.push(root);
while (q.size()!=0)
{
n = q.front();
cout << n->key << " " << n->value<<" "<<n->count << endl;
if (n->left!=NULL)
q.push(n->left);
if(n->right!=NULL)
q.push(n->right);
q.pop();
}
}
//三种删除
void removeMin()
{
root = removeMin(root);
}
Node* removeMin(Node *node)
{
if (node->left != NULL)
node->left = removeMin(node->left);
else
{
delete node;
count--;
return NULL;
}
(node->count)--;
return node;
}
void removeMax()
{
root = removeMax(root);
}
Node* removeMax(Node* node)
{
if (node->right != NULL)
node->right = removeMax(node -> right);
else
{
delete node;
count--;
return NULL;
}
(node->count)--;
return node;
}
void remove(Key key)
{
if(contain(key)!=false && root!=0)
root = remove(root, key);
}
Node* remove(Node* node, Key key)
{
(node->count)--;
//cout<<"count="<<node->count<<endl;
if (node == NULL)
return NULL;
if (key < node->key)
node->left = remove(node->left, key);
else if (key > node->key)
node->right = remove(node->right, key);
else if(node->key == key)
{
if (node->left == NULL && node->right == NULL)
{
delete node;
count--;
return NULL;
}
if (node->left == NULL)
{
Node* nl = node->right;
delete node;
count--;
return nl;
}
if (node->right == NULL)
{
Node* nr = node->left;
delete node;
count--;
return nr;
}
//寻找右子树最小的值
Node *delNode = node;
Node *newNode = new Node( minimum(node->right) );
if (newNode = node->right)
{
newNode->count = node->count - 1;
newNode->left = node->left;
delete node;
count--;
return newNode;
}
else
{
newNode->left = node->left;
newNode->right = node->right;
removeMin(node->right);
newNode->count = node->count;
count--;
return newNode;
}
//Node *minNode =
//newNode = new Node(minNode->key, minNode->value);
//newNode->left = minNode->left;
//newNode->right = minNode->right;
//newNode->count = minNode->count;
count++;
removeMin(newNode);
newNode->right = node->right;
newNode->left = node->left;
delete delNode;
count--;
return newNode;
}
return node;
}
//顺序性value前一个元素和后一个元素
Value* successor(Key key){}
Value* predecessor(Key key) {}
//一个不存在树中的元素Key 的距离最近的值
Value* floor(Key key) {}
Value* ceil(Key key) {}
//index是排名第几的元素
int rank(Key key) {}
//排名第index的元素是谁
Value* select(int index) {}
};
读取文件,我这里直接读取了圣经英文版全文
int test()
{
vector<string> words;
duqu("D://圣经英文版.txt", words);
cout << "总共有单词" << words.size() << endl;
int size = words.size();
BST2<string, int> s;
cout << "正在构建树" << endl;
clock_t startTime = clock();
for (int i = 0; i < size; i++)
{
//cout << "在树中插入第" << i << "个单词 "<< words[i] << endl;
s.insert(words[i], 1);
}
clock_t endTime = clock();
cout << "构建树所用的时间" << double(endTime - startTime) / CLOCKS_PER_SEC << " S" << endl;
cout << "构建完成,树中共有节点 " << s.size() << endl;
s.maximnm();
cout << "输入想要查找出现次数的单词" << endl;
while (0)
{
string a;
cin >> a;
startTime = clock();
int* b;
if (s.contain(a) == true)
{
cout << "有这个单词" << endl;
b = s.search(a);
cout << *b << endl;
}
else
cout << "没有这个单词" << endl;
endTime = clock();
cout << "二分搜索树查找需要用时间 " << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
startTime = clock();
int x = count(words.begin(), words.end(), a);
endTime = clock();
cout << "vector的count方法查找有 " << x << "个 用时" << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
}
}
在附上简单的测试代码,可以自己运行测试
int test()
{
vector<string> words;
duqu("D://test.txt", words);
cout << "总共有单词" << words.size() << endl;
int size = words.size();
BST2<string, int> s;
cout << "正在构建树" << endl;
clock_t startTime = clock();
for (int i = 0; i < size; i++)
{
//cout << "在树中插入第" << i << "个单词 "<< words[i] << endl;
s.insert(words[i], 1);
}
clock_t endTime = clock();
cout << "构建树所用的时间" << double(endTime - startTime) / CLOCKS_PER_SEC << " S" << endl;
cout << "构建完成,树中共有节点 " << s.size() << endl;
s.maximnm();
cout << "输入想要查找出现次数的单词" << endl;
while (1)
{
string a;
cin >> a;
startTime = clock();
int* b;
if (s.contain(a) == true)
{
cout << "有这个单词" << endl;
b = s.search(a);
cout << *b << endl;
}
else
cout << "没有这个单词" << endl;
endTime = clock();
cout << "二分搜索树查找需要用时间 " << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
startTime = clock();
int x = count(words.begin(), words.end(), a);
endTime = clock();
cout << "vector的count方法查找有 " << x << "个 用时" << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
}
return 0;
}