原始kd树的构建和显示(递归实现)

来源:互联网 发布:智能电视网络设置 编辑:程序博客网 时间:2024/05/02 02:42

算法详细原理描述请百度,这里只是实现最简单的建树和显示,为了便于理解,代码尽可能简短。

#include<iostream>#include<cmath>#include<string>#include<algorithm>#include<vector>using namespace std;//训练数据int data[6][2]={{2,3},{5,4},{9,6},{4,7},{8,1},{7,2}};//树节点struct KdTree{vector<double>data;  //节点数据KdTree *leftChild;  //左孩子KdTree *rightChild;  //右孩子KdTree *parent;KdTree(){leftChild=rightChild=parent=NULL;}bool isempty()  //返回节点数据是否为空{return data.empty();}};template<typename T>vector<vector<T>>Trans(vector<vector<T>>Maxrix){unsigned row=Maxrix.size();unsigned col=Maxrix[0].size();  //获取数组的行和列vector<vector<T>>vec(col,vector<T>(row,0));  //构造一个转置的矩阵for(unsigned i=0;i<row;i++)for(unsigned j=0;j<col;j++)vec[j][i]=Maxrix[i][j];return vec;}template<typename T>T getMiddleValue(vector<T>data){unsigned s=data.size(); //获取数组大小sort(data.begin(),data.end());  //执行排序return data[s/2];  //返回中位数}void buildTree(KdTree *tree,vector<vector<double>>data,int depth){unsigned row=data.size();  //获取数据的总有多少个元素if(row==0)return;if(row==1)  //如果集合中还有一个数据就将当前数据赋值给节点{tree->data=data[0];return;}//如果还有多个数据以上unsigned k=data[0].size();  //获取当前数据的维度unsigned current=depth%k;  //当前比较的数据维度vector<vector<double>>currentVec=Trans(data);   //数据 转置vector<double>transVec=currentVec[current];  //获取当前要比较的数值数组double middle=getMiddleValue(transVec);  //获取中位数vector<vector<double>>subSet1;vector<vector<double>>subSet2;for(unsigned i=0;i<row;i++){if(data[i][current]==middle&&tree->data.empty())tree->data=data[i];else{if(data[i][current]<middle)subSet1.push_back(data[i]);elsesubSet2.push_back(data[i]);}}//处理孩子tree->leftChild=new KdTree;  //生成子节点tree->rightChild=new KdTree;tree->leftChild->parent=tree;tree->rightChild->parent=tree;buildTree(tree->leftChild,subSet1,depth+1);  //递归建立树buildTree(tree->rightChild,subSet2,depth+1);}//打印树void printTree(KdTree *tree,int depth){if(!tree)  //如果树空就返回return;for(unsigned i=0;i<tree->data.size();i++)  //输出节点数据{cout<<tree->data[i]<<" ";}cout<<endl;if(tree->leftChild)  //左孩子存在输出左孩子{for(int i=0;i<depth+1;i++)cout<<"\t";cout<<"left:";printTree(tree->leftChild,depth+1);  //打印左孩子}cout<<endl;if(tree->rightChild){for(int i=0;i<depth+1;i++)cout<<"\t";cout<<"right:";printTree(tree->rightChild,depth+1);  //打印右孩子}}int main(){vector<vector<double>> treedata(6,vector<double>(2,0));  //定义6行2列数组for(unsigned i=0;i<6;i++)for(unsigned j=0;j<2;j++)treedata[i][j]=data[i][j];//构建节点KdTree *tree=new KdTree;buildTree(tree,treedata,0);printTree(tree,0);return 0;}


0 0