排序二叉树的c++实现
数据结构中的二叉树一直都是面试中的常考题,之前和师兄讨论深度学习的问题时他说我连二叉树都不会还想深度学习?感受到深深的挫折后开始学习数据结构,下面是我对二叉树的理解,所有代码可运行。
因为是一个较小的demo,并且本着方便初学者学习的原则,采用定义和实现在同一代码块,方便阅读。注意,所有函数方法都需要在类中。分类的小代码块只为了方便大家理解原理,整个代码附在最后,不想看我bb叨的朋友们点击目录的链接,跳转到二叉搜索树(BST)的完整代码 去Ctrl-C吧。
定义一个节点类
class BiNode{
public:
int data;
BiNode *lchild,*rchild;
BiNode(){
lchild=rchild=NULL;
}
BiNode(int value){
this->data=value;
lchild=rchild=NULL;
}
};
定义一个二叉树类
有小伙伴可能会问:成员属性只有一个根节点?构造时还被初始化为0?wtf? 这么简单?
别急,这正体现链式存储结构的特点,只需要一个根,就能调用根下链接的N个数据。就像牵一个毛衣的线头就能一直拉出几十米长的毛线。类中的成员函数会在后文一一介绍。
class BiTree{
private:
BiNode * root;
BiTree(){
root=NULL;}
};
添加节点
添加节点需要用到递归:先定义一个引用类型的临时节点,向这个临时节点添加新的数据,如果该临时节点为空,那么就把该数据作为临时节点。如果该临时节点已经有数据,那么就和他作比较,如果比他大,就去右边的节点。如果比他小,就去插他的左节点。如果一样,那就啥也不干。
void add(int value ,BiNode * &temp){
if(temp==NULL){
temp=new BiNode(value);
return;
}
if(value<temp->data){
add( value,temp->lchild);}
else if (value>temp->data){
add(value,temp->rchild);}
else{
return;}
}
在外部的调用时,我们通常喜欢更简洁的调用方式,只输入想要加入二叉树的值就行,因此重载该函数,始终对根节点进行插入,他会递归调用上面的add函数,找到自己该去的位置。
void add(int value){
add(value,this->root);
}
删除节点
void deleteNode(int value){
if(this->root==NULL){
cout<<"空树"<<endl;
return ;
}
if(this->root->data==value){
this->root=NULL;
return ;
}
deleteNode(value,this->root);
}
计算二叉树深度
计算深度同样需要用到递归的方法,该函数始终计算的是输入地temp节点的深度,如果当前节点为空返回0,如果不为空则返回左子树或右子树的深度最大的值,再加上1。
int getHeight(BiNode *temp){
if(temp==NULL){
return 0;
}
int hl=getHeight(temp->lchild);
int hr=getHeight(temp->rchild);
if(hl>=hr)return ++hl;
else return ++hr;
}
重载:
int getHeight(){
return(getHeight(this->root));
}
各种遍历方法
常用遍历方法包括前序遍历,中序遍历,后序遍历,深度优先遍历,广度优先遍历。
前序遍历:当前节点->左子节点->右子节点
中序遍历:左子节点->当前节点->右子节点
后序遍历:左子节点->右子节点->当前节点
前序遍历
void pre_Order(const BiNode * t){
if(t==NULL){
return;}
cout<<t->data<<" ";
pre_Order(t->lchild);
pre_Order(t->rchild);
}
重载方便输出到屏幕,当然如果你愿意每次调用的时候都输入形参root,也不用写重载函数:
void preOrder(){
if(this->root==NULL){
cout<<