关于二叉树的建立,根据前序和中序,建立二叉树。并且总结关于二叉树前序,中序以及后序的非递归遍历。
1、二叉树的建立
利用递归的思想建立二叉树,如pre[]={8,11,9,3,13,6,15,12,5,7}; mid[]={3,9,13,11,6,15,8,5,12,7}分别代表前序和中序的遍历结果。前序结果中的第一个元素为8,为根节点,中序遍历中mid[0]~mid[5]是8的左子树,左子树的根节点为11,mid[7]~mid[9]为右子树,其根节点为12。建立以8为根的二叉树,就可以转换为建立以11为根的节点8的左子树,和以12为根的节点8的右子树。通过递归调用,构建二叉树。
2、二叉树的非递归前序遍历
前序遍历优先访问根节点,在访问左子树的根节点,在右子树的根节点。访问顺序为根->左孩子->右孩子。利用栈来存储节点,每遇到一个节点,则提取数据。
- 设置根节点为当前节点cur,不为空入栈;
- 左孩子是否为空,不为空则持续入栈,提取数据,更新当前节点为root。为空则出栈,更新出栈元素的右孩子为当前节点;
- 结束条件,栈为空。
3、二叉树的非递归中序遍历
中序遍历的顺序为,左孩子->根节点->右孩子。
- 设置根节点为当前节点cur,不为空入栈;
- 左孩子是否为空,不为空,入栈,并更新左孩子为当前节点,入栈直至为空;
- 当前节点为空,出栈;提取数据,更新右孩子为当前节点。
- 结束条件,栈为空。
4、二叉树的非递归后序遍历
后序遍历的顺序为,左孩子->右孩子->根节点。需要设置一个最近的遍历节点,以判断右孩子是否已遍历。
- 设置根节点为当前节点cur,不为空则入栈;
- 左孩子是否为空,不为空,则入栈,并更新左孩子为当前节点,入栈直至为空;
- 当前节点为空,提取头结点为当前节点;判断右孩子为空,或者右孩子已访问,则提取数据,出栈,更新previsited;
- 若右孩子不为空,且未访问,则设置右孩子为当前节点;
- 结束条件,栈为空。
#include<iostream> #include<stack> using namespace std; struct node{ int value; node* left; node* right; node(int value):value(value),left(NULL),right(NULL){} ~node(){} }; node* _build_tree(int pre[],int start_pre,int mid[],int start_mid, int len){ int value = pre[start_pre]; node* root = new node(value); int index=0; for(int i=start_mid;i<start_mid+len;i++){ if(value==mid[i]){ index = i; break; } } int left_len = index-start_mid;//左子树的长度 if(left_len>0)root->left = _build_tree(pre,start_pre+1,mid,start_mid,left_len); int right_len = start_mid+len-index-1;//右子树的长度 if(right_len>0)root->right = _build_tree(pre,start_pre+left_len+1,mid,index+1,right_len); return root; } //Create bitree according to the pre_order, and mid_order; node* build_tree(int pre[],int mid[],int len){ node* head=NULL; head=_build_tree(pre,0,mid,0,len); return head; } //Non-recursive pre-order void pre_order_non(node* root){ stack<node*> st; node* cur = root; while(cur!=NULL||!st.empty()){ while(cur!=NULL){ cout<<cur->value<<endl; st.push(cur); cur=cur->left; } cur = st.top(); st.pop(); cur = cur->right; } } //Non-recursive mid-order void mid_order_non(node* root){ //node* pnode = root; stack<node*> st; node* cur = root; while(cur!=NULL||!st.empty()){ while(cur!=NULL){ st.push(cur); cur = cur->left; } cur = st.top(); cout<<cur->value<<endl; st.pop(); cur = cur->right; } } //Non-recursive post-order void post_order_non(node* root){ stack<node*> st; node* cur = root; node* previsited = NULL; while(cur!=NULL||!st.empty()){ while(cur!=NULL){ st.push(cur); cur = cur->left; } cur = st.top(); if(cur->right==NULL||cur->right==previsited){ cout<<cur->value<<endl; st.pop(); previsited = cur; cur = NULL; }else cur=cur->right; } } int main(){ int length = 10; int pre[]={8,11,9,3,13,6,15,12,5,7}; int mid[]={3,9,13,11,6,15,8,5,12,7}; node* root = build_tree(pre,mid,length); mid_order_non(root); post_order_non(root); pre_order_non(root); system("pause"); }