k近邻法中kd-tree树的创建
来源:互联网 发布:exsi虚拟机linux网络 编辑:程序博客网 时间:2024/06/06 00:58
经过一天努力实现了kd-tree树二维的创建,但是代码只适用于二维,这是令人遗憾的地方。
在这个过程中学到了不少东西,特别是对vector的一些用法,多了更多的了解。
思路:创建树时,传递vector为形参,以第n%2维为变量,对结构体vector排序,找出中位数,奇数找中间,
偶数取第(n/2)+1个,以它为分界线,左边的放在vector<>a中,右边的数放在vector<>b中,中位数那个点,
保存为节点,递归调用创建左右子树。
代码限制普适性的地方:1、创建了点的结构体
2、找到操作维数,并对其操作的代码
学到的用法:
1、vector可当形参,而且跟其他形参一样,函数中的操作可不影响原vector
#include<iostream>#include<vector>using namespace std;void f(vector<int> x){x[0]=0;}int main(){vector<int> a;a.push_back(1);a.push_back(2);f(a);cout<<a[0];return 0;}
结果:
2、istringstream的运用,对于数据的输入很方便
void kdTree::dataIn(){ifstream in("data.txt");string str;for(int i=0;i<N;i++){getline(in,str);istringstream t(str);t>>dataValue[i].x;t>>dataValue[i].y;}}
3、c++访问控制
第一:private, public, protected 访问标号的访问范围。
private:只能由1.该类中的函数、2.其友元函数访问。
不能被任何其他访问,该类的对象也不能访问。
protected:可以被1.该类中的函数、2.子类的函数、以及3.其友元函数访问。
但不能被该类的对象访问。
public:可以被1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由4.该类的对象访问。
注:友元函数包括3种:设为友元的普通的非成员函数;设为友元的其他类的成员函数;设为友元类中的所有成员函数。
第二:类的继承后方法属性变化。
private 属性不能够被继承。
使用private继承,父类的protected和public属性在子类中变为private;
使用protected继承,父类的protected和public属性在子类中变为protected;
使用public继承,父类中的protected和public属性不发生改变;
4、vector的排序
bool SortByX( const Point &v1, const Point &v2)//注意:本函数的参数的类型一定要与vector中元素的类型一致 { return v1.x < v2.x;//x按升序排列 }
sort(v.begin(),v.end(),SortByX);
kd-tree创建
#include<iostream>#include<fstream>#include <sstream>#include<string>#include<vector>using namespace std;const int N=6;//the number of sample//const int K=2;//the div of sample//vector<int> T;// 1thclass Point{public: int x; int y;} ;vector<Point> R;class kdTreeNode{public:Point value;kdTreeNode*left;kdTreeNode*right;};class kdTree{ public: kdTreeNode*head; Point dataValue[N];void dataIn();//从文件中输入数据 void dataOut();//查看dataValue[N]中数据 void dataOperate();//预处理 kdTreeNode*createTree(vector<Point> v,int n);//创建树 void lookKdTree(kdTreeNode*p);//先根遍历 };void kdTree::dataIn(){ifstream in("data.txt");string str;for(int i=0;i<N;i++){getline(in,str);istringstream t(str);t>>dataValue[i].x;t>>dataValue[i].y;}}void kdTree::dataOut(){for(int i=0;i<N;i++){cout<<dataValue[i].x<<'\t';cout<<dataValue[i].y<<endl; }}void kdTree::dataOperate(){for(int i=0;i<N;i++)R.push_back(dataValue[i]);}bool SortByX( const Point &v1, const Point &v2)//注意:本函数的参数的类型一定要与vector中元素的类型一致 { return v1.x < v2.x;//x按升序排列 }bool SortByY( const Point &v1, const Point &v2)//注意:本函数的参数的类型一定要与vector中元素的类型一致 { return v1.y < v2.y;//y按升序排列 } kdTreeNode* kdTree::createTree(vector<Point> v,int n){if(v.empty())return NULL;kdTreeNode*p=new kdTreeNode;if(n%2==0){sort(v.begin(),v.end(),SortByX);p->value=v[v.size()/2];vector<Point> a;vector<Point> b;for(int i=0;i<v.size()/2;i++) a.push_back(v[i]); for(int i=v.size()/2+1;i<v.size();i++) b.push_back(v[i]); p->left=createTree(a,n+1); p->right=createTree(b,n+1);} else{sort(v.begin(),v.end(),SortByY);p->value=v[v.size()/2];vector<Point> a;vector<Point> b;for(int i=0;i<v.size()/2;i++) a.push_back(v[i]); for(int i=v.size()/2+1;i<v.size();i++) b.push_back(v[i]); p->left=createTree(a,n+1); p->right=createTree(b,n+1);}return p;}void kdTree::lookKdTree(kdTreeNode*p){if(p==NULL)return;cout<<p->value.x<<'\t'<<p->value.y<<endl;lookKdTree(p->left);lookKdTree(p->right);}int main(){kdTree tree;tree.dataIn();//tree.dataOut();tree.dataOperate();tree.head=tree.createTree(R,0);tree.lookKdTree(tree.head);return 0;}
输入:
data.txt
2 3
5 4
9 6
4 7
8 1
7 2
输出:
7 2
5 4
2 3
4 7
9 6
8 1
1 0
- k近邻法中kd-tree树的创建
- k近邻法的实现:kd树
- k近邻法的实现:kd树
- K近邻法、kd树
- k近邻算法与kd树的创建和搜索
- kd-tree和K近邻
- K近邻,kd树
- K近邻-kd树
- 统计学习方法----k近邻法的实现:kd树
- k近邻算法的实现:kd树
- k近邻算法的实现:kd树
- k近邻法与kd树
- k近邻法与kd树
- k近邻法与kd树
- k近邻法之kd树
- 最近邻法和k-近邻法 KD树
- k近邻算法(KNN)及kd树简介(KD-Tree)
- K近邻算法基础:KD树的操作
- Photoshop问题:保存图片时出现“无法完成请求,因为程序错误”
- 稀疏——字典学习
- struts2 动态方法调用
- Cocos2d-x Android修改ICON名字、更改图标、修改屏幕方向、修改版本号
- 1410501134
- k近邻法中kd-tree树的创建
- 下载网络文件HttpURLConnection.getContentLength()大小为 -1
- 触摸事件
- ios简单的功能类的封装
- 字符串的全排列——《编程之法》课后题答案
- 动态规划之矩阵链乘法(第15章)
- md5校验
- 多渠道打包
- 不规则区域的点击事件判断