摘要
在学STL的关联容器的时候,遇到了一些树,这里把它实现一下
BST
Win QT + MinGW 5.4 + C++11
#include <QCoreApplication>
#include <iostream>
#include <vector>
using namespace std;
// 这里只实现int Tree, 对于泛型T需要用到Traits
namespace WY_Tree{
struct Tree{
private:
vector<int> *v = nullptr;
const int MAX_INT = 999999;
const int zwf = 999998; //占位符
enum _Tree_Type{
original,
BST
};
public:
_Tree_Type Tree_Type=original;
private:
/* 构造一个基础树 */
vector<int>* new_tree(){
vector<int> *new_t = new vector<int>();
new_t->push_back(MAX_INT);
return new_t;
}
/* 获取当前节点的父亲节点的index */
int father(const int& index){
if(0==index || 1==index){
return index;
}
else{
return index>>1;
}
}
int left_child(const int& index){
if(0==index){
return index;
}
return index<<1;
}
int right_child(const int& index){
if(0==index){
return index;
}
return (index<<1) + 1;
}
public:
/*
* 重构当前树为二叉搜索树
* 注意:占位符 zwf 不能出现在树中
*/
void make_BST(){
if(this->v == nullptr){
cout<<"Error: (1000) Current tree has no content"<<endl;
return ;
}
vector<int> *new_t = WY_Tree::Tree::new_tree();
vector<int> *old_t = WY_Tree::Tree::new_tree();
/* 将原始树还原到没有占位符的状态 */
for(auto itr = this->v->begin()+1; itr!=this->v->end(); ++itr){
if(*itr!=zwf){
old_t->push_back(*itr);
}
}
/* 从旧数组中逐个取出元素插入到新的BST中去 */
int old_size = old_t->size();
for(int i=1; i<old_size; ++i){
int new_value = old_t->at(i);
int cur_size = new_t->size();
int cur_index = 1; //从root开始
while(1){
/* 如果待插入位置越界,则往vector插入zwf占位*/
if(cur_index>=cur_size){
int distance = cur_index-cur_size+1;
for(int j=0; j<distance; ++j){
new_t->push_back(zwf);
}
}
if(new_t->at(cur_index) == zwf){
(*new_t)[cur_index] = new_value;
break;
}
else if(new_t->at(cur_index) >= new_value){
cur_index = this->left_child(cur_index);
}
else{
cur_index = this->right_child(cur_index);
}
}
}
/* 将重构后的BST绑定到类中 */
delete this->v;
delete old_t;
this->v = new_t;
this->Tree_Type = BST;
}
int search_BST(const int& target){
if(this->Tree_Type != BST){
return 0;
}
int cur_index = 1;
auto cur_tree = this->v;
int itr_count = 0;
while(1){
/* 越界 */
if(cur_index >= cur_tree->size()){
cout<<"Cannot find: "<<target<<endl;
return 0;
}
++itr_count;
int cur_value = cur_tree->at(cur_index);
if( cur_value==zwf ){
cout<<"Cannot find: "<<target<<endl;
return 0;
}
else if( target < cur_value ){
cur_index = this->left_child(cur_index);
}
else if( target > cur_value){
cur_index = this->right_child(cur_index);
}
else{
cout<<"Found: "<<target<<" at index of "<<cur_index<<" in "<<itr_count<<" iterations "<<endl;
return itr_count;
}
}
}
/* 打印当前树 */
void print(){
if(this->v->empty()){
cout<<"The Tree is Empty"<<endl;
}
for(auto itr = (this->v->begin()+1); itr!= this->v->end(); itr++){
if((*itr)==zwf){
cout<<0<<" ";
}else{
cout<<(*itr)<<" ";
}
}
cout<<endl;
}
public:
Tree(){
this->v = WY_Tree::Tree::new_tree();
};
Tree(const vector<int>& new_v){
this->v = WY_Tree::Tree::new_tree();
for(int i=0; i<new_v.size(); ++i){
this->v->push_back(new_v.at(i));
}
}
~Tree(){
if(this->v!=nullptr) {
delete this->v;
}
}
};
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
vector<int> v{17,12,19,10,15,18,25,8,11,13,16,26};
WY_Tree::Tree t(v);
t.make_BST(); //构造一棵BST
t.print();
double BST_Average_Iterations = 0;
for(auto itr=v.begin(); itr!=v.end(); ++itr){
BST_Average_Iterations+=t.search_BST(*itr);
}
cout<<"Average Iterations BST : "<<BST_Average_Iterations/v.size()<<endl;
return a.exec();
}
结果
这里简单的计算了搜索vector中所有数字的平均次数