目录
1.定义二叉树
//定义二叉树的节点 struct node{ int val; //节点的值 node *left; //定义左孩子 node *right; //定义右孩子 node(int x):val(x),left(NULL),right(NULL){} //在建立新的节点时使指针为空,下边的写法也可以 //node(int val=0,node *left=NULL,node*right=NULL):val(val),left(left),right(right){} };
2.根据题目给出的数据构建二叉树
(1)知道先序遍历和中序遍历,构建树
void buildtree(int l,int r,int &t,node *&root){ int flag=-1;//判断是否遍历完先序啥 for(int i=l;i<=r;i++){//先序中的第一个数是根,所以引用的t是从1开始的,找到对应的中序的位置 if((in[i]==per[t])) { flag=i;break;//找到了就跳出循环-->建立新的节点 } } if(flag==-1) return;//结束 root=new node(in[flag]);//新建节点 t++;//前序变成下一个节点 //从(l,flag-1)在父节点的左侧建树(因为已知根节点,在中序中,在此根节点的左侧的点都在左子树上),flag+/-1是为了避开第一个父节点 ,右子树同理 if(flag>l) buildtree(l,flag-1,t,root->left);//l是数据的左端r是数据的右端,t是先序遍历中根节点的下标 if(flag<r) buildtree(flag+1,r,t,root->right); }
(2)知道后序遍历和中序遍历,构建树
void build(int l,int r,int &t,node *&root){//t应该是后序的最后一位(应用的t应该是n),然后从后向前遍历(因为后序遍历的最后一个数是根节点) int flag=-1;//!! for(int i=l;i<=r;i++) //中序不需要管遍历顺序吧 if(in[i]==post[t]){ flag=i;break; } if(flag==-1) return ; // root=new node(in[flag]); // t--;与上一个代码的不同 /知道中序和后序,先递归右子树;;;知道先序和中序,先递归左子树 if(flag<r) build(flag+1,r,t,root->right); if(flag>l) build(l,flag-1,t,root->left); }
3.四种遍历
(1)先序遍历
void qian(node*root){ if(root!=NULL){ per[k++]=root->val;//输入根节点的值,per[]中按顺序输入先序遍历过的根节点的值 qian(root->l); //递归左子树 qian(root->r); //递归右子树 } }
(2)中序遍历
void zhong(node*root){ if(root!=NULL){ zhong(root->l); in[k++]=root->val;//in[]中是按中序遍历的根节点 zhong(root->r); } }
(3)后序遍历
void hou(node*root){ if(root!=NULL){ hou(root->l); hou(root->r); post[k++]=root->val;//post[]中是按后序遍历的根节点 } }
(4)层序遍历
用到queue:其想法就是从最上层的根节点开始,将其加入到队列中,然后输出,在删除这个元素(因为此函数传入的是根节点的地址T,所以在队列中加入或者删除元素不会改变传入的地址),并且判断这个根节点是否还有左右孩子,如果有就先让左孩子加入到队列中,再让右孩子,当根节点不再有孩子,队列为空时,无需再向下找
void level(node *T,int n){//传入的n是为了控制空格的输出,只要求两个数之间有空格,最后一位数后边没有空格 //node* queue<node*>queue;//队列命名为了queue!!!!其类型一定是node*(前往不要忘记*) queue.push(T);//根节点放入队列 while(!queue.empty()){//如果队列不为空,下面三部走 //1. T=queue.front();//对头元素出队,指针重新指向,front.()是将返回头元素但不删除 printf("%d",T->val);//父节点出队后,将左右孩子放入队列; if(n!=1) cout<<" "; n--; queue.pop();//删除队首元素 //2. if(T->left!=NULL) queue.push(T->left);//如果首元素的左子树不是空,将其左子树放入队列 //入对的是一个地址元素 //3. if(T->right!=NULL) queue.push(T->right); } }
4.释放空间
void re_free(node *root){ if(root==NULL) return ; re_free(root->left); re_free(root->right); delete root; }
5.加上主函数