Binary tree 基础

来源:互联网 发布:域名询价 编辑:程序博客网 时间:2024/06/06 07:30

整理了一下关于二叉树的各种操作,为了方便直接全程使用排序二叉树。涉及到的有如下的几种功能:


1、定义二叉树数据结构;

2、由前序遍历及中序遍历构造二叉树;

3、将一组数构造成二叉搜索树;

4、求二叉树的高度;

5、查找某个结点的递归与非递归实现;

6、在指定位置插入的实现(递归与非递归);

7、寻找最大、最小结点的递归与非递归实现;

8、删除指定结点;


首先是定义相应的数据结构类型,此处结合struct和class来实现。一开始定义的

typedef int T;

可方便地对数据类型进行修改

#include<iostream>#include<algorithm>#include<cmath>using namespace std;typedef int T;typedef struct treenode{T value;treenode *left,*right;}treenode;static treenode* build_node(T value)//创建结点 {treenode* tree=new treenode;tree->value=value;tree->left=NULL;tree->right=NULL;return tree;}class Btree{static int n,m;public:Btree(){root=NULL;}void creat_Bsearch_tree(T x);//建立二叉查找树;T GetHeight();    //求树高; protected:    T GetHeight(treenode*);private:treenode* root;};

之后是由已知数组直接构造二叉搜索树的操作以及求树的高度。

void Btree::creat_Bsearch_tree(T x)//建立排序二叉树 规则是 {treenode *newnode=new treenode;newnode->value=x;newnode->left=NULL;newnode->right=NULL;if(root=NULL){root=newnode;}else{treenode *back,*current=root;while(current!=NULL){back=current;if(current->value>x){current=current->left;}else{current=current->right;}}if(back->value>x){back->left=newnode;}else{back->right=newnode;}}}T Btree::GetHeight(treenode* tree)  //求二叉树的高度 {      if(tree==0) return 0;      else      {          int l_h=GetHeight(tree->left);          int r_h=GetHeight(tree->right);          return (l_h>r_h) ? l_h+1:r_h+1;      }  }

然后是由先序遍历以及中序遍历序列来构造二叉树。

//由先序遍历及中序遍历建立二叉树 treenode* fm_creat_Btree(T preOrder[],T p_l,T p_r,T inOrder[],T i_l,T i_r){if((p_r-p_l)!=(i_r-i_l)||p_r<p_l)    {return NULL;  //当两个遍历序列长度不一或始位置大于末位置时}//第一个元素是先序遍历的第一个元素,是根结点 treenode* tree=(treenode*)malloc(sizeof(treenode));tree->value=preOrder[p_l];tree->left=NULL;tree->right=NULL;if(p_l==p_r){return tree;//显然是只有一个点的树 }//在中序遍历中寻找根结点T itemp;for(itemp=i_l;itemp<=i_r;itemp++){if(inOrder[itemp]==preOrder[p_l]){break;}} if(itemp>i_r){return NULL;    //找不到的情况 }T length;if(itemp>i_l)//有左叶子时,递归调用 {length=itemp-i_l;tree->left=fm_creat_Btree(preOrder,p_l+1,p_l+length,inOrder,i_l,i_l+length-1);} if(itemp<i_r)//有右叶子时,递归调用 {length=i_r-itemp;tree->right=fm_creat_Btree(preOrder,p_r-length+1,p_r,inOrder,i_r-length+1,i_r);}return tree;}
之后是分别采用递归或非递归思想来实现的查找、插入。

treenode* re_search(treenode* tree,T x)//查找关键字为x的结点(递归) {if(tree->value==x){return  tree;}else if(tree->value>x){if(tree->left!=NULL){return re_search(tree->left,x);}else{return NULL;}}else if(tree->value<x){if(tree->right!=NULL){return re_search(tree->right,x);}else{return NULL;}}}treenode* search(treenode* tree,T x)//查找关键字为x的结点(非递归) {if(!tree){return NULL;}treenode* p=tree;while(p){if(p->value<x){p=p->right;}else if(p->value>x){p=p->left;}return p;}return NULL;}treenode* re_BSTinsert(treenode* tree,T x)//排序二叉树的插入(递归) {if(!tree){return build_node(x);}if(tree->value>x){tree->left=re_BSTinsert(tree->left,x);}else{tree->right=re_BSTinsert(tree->right,x);}return tree;}treenode* BSTinsert(treenode* tree,T x)//排序二叉树的插入(非递归) {treenode* p;treenode* p_f;//p_f为待插入结点的父结点 p=tree;p_f=NULL;while(p){p_f=p;if(p->value<x){p=p->right;}else{p=p->left;}if(tree==NULL){tree=build_node(x);return tree;}else{if(p_f->value<x){p_f->right=build_node(x);}else{p_f->left=build_node(x);}return tree;}}}treenode* re_findmax(treenode* tree)//寻找最大结点(递归) {if(tree->right==NULL){return tree;}else{re_findmax(tree->right);}}treenode* findmax(treenode* tree)//寻找最大结点(非递归){treenode* p;p=tree;while(p->right){p=p->right;}return p;} treenode* re_findmin(treenode* tree)//寻找最小结点(递归){if(tree->left==NULL){return tree;}else{re_findmin(tree->left);}} treenode* findmin(treenode* tree)//寻找最小结点(非递归){treenode* p;p=tree;while(p->left){p=p->left;}return p;} 
最后是删除的操作。

treenode* remove(treenode* tree,T x)//删除指定结点 {if(!tree){return NULL;}treenode* back;if(x==tree->value){if(tree->left==NULL)//没有左子树的情况 {back=tree;tree=tree->right;delete back;}else if(tree->right==NULL)//没有右子树的情况 {back=tree;tree=tree->left;delete back;}else//寻找前驱替代(有左右子树) {treenode* temp;temp=findmax(tree->left);tree->value=temp->value;remove(tree->left,temp->value);}}else if(x<tree->value)//递归调用以查找 {remove(tree->left,x);}else if(x>tree->value){remove(tree->right,x);}}
总结后发现在对于二叉树的操作中,不止一次地需要领会理解递归,这也和二叉树在此处采用了单链表的存储方式有莫大的关系。

0 0
原创粉丝点击