C语言 二叉树的遍历(递归和非递归)
#include <iostream> #include <cstdio> #include "biTree.h" #include "cstdlib" #define OVERFLOW -1 #include <stack> using namespace std; Status CreateBiTree( BiTree &T ) { int a; printf( "Creating BiTree .....\n" ); printf( "input: <number>:" ); scanf( "%d",&a ); if ( a==0 ) { T=NULL; } else { T=( BiTree )malloc( sizeof( BiTNode ) ); if ( !T ) exit( OVERFLOW ); T->data=a; CreateBiTree( T->lchild ); CreateBiTree( T->rchild ); } return OK; } Status PreOrderTraverse( BiTree T,Status( * Visit )( TElemtype e ) ) { if ( T ) { Visit( T->data ); PreOrderTraverse( T->lchild,Visit ); PreOrderTraverse( T->rchild,Visit ); } return OK; } Status InOrderTraverse( BiTree T,Status( *Visit )( TElemtype e ) ) { if ( T ) { InOrderTraverse( T->lchild,Visit ); Visit( T->data ); InOrderTraverse( T->rchild,Visit ); } return OK; } Status PostOrderTraverse( BiTree T,Status( *Visit )( TElemtype e ) ) { if ( T ) { PostOrderTraverse( T->lchild,Visit ); PostOrderTraverse( T->rchild,Visit ); Visit( T->data ); } return OK; } Status InOrderTraverseNoDG( BiTree T,Status( *Visit )( TElemtype e ) ) { stack<BiTree> st; BiTree p=NULL; st.push( T ); while ( !st.empty() ) { while ( ( p=st.top() )&&p ) { st.push( p->lchild ); } st.pop();//走到头然后继续往右 if ( !st.empty() ) { p=st.top(); st.pop(); if ( !Visit( p->data ) ) return ERROR; st.push( p->rchild ); //输出根之后 在栈顶(当前节点)继续往左循环 } } return OK; } Status PreOrderTraverseNoDG( BiTree T,Status( *Visit )( TElemtype e ) ) { stack<BiTree> st; BiTree p=NULL; st.push( T ); while ( !st.empty() ) { while ( ( p=st.top() )&&p ) { if ( !Visit( p->data ) ) return ERROR; st.push( p->lchild ); } st.pop();//走到头然后继续往右 if ( !st.empty() ) { p=st.top(); st.pop(); st.push( p->rchild ); //输出根之后 在栈顶(当前节点)继续往左循环 } } return OK; } Status PostOrderTraverseNoDG( BiTree T,Status( *Visit )( TElemtype e ) ) { /* 如果不使用标志位区分第几次到达根结点, 可以利用如下的后序遍历特征来完成:当栈顶元素(根)的右子树为空(即:无右孩子), 或者是右子树非空但是已遍历完,即右孩子恰好是刚才访问过的结点, 此时应访问栈顶结点,并在访问后退栈 否则,如果栈顶元素的右孩子非空且未遍历, 此时直接访问栈顶元素的右孩子而不退栈, 算法要点只是需要记住最近访问过的结点即可 */ BiTree p=T; stack <BiTree> st; BiTree have_visited=NULL; while ( NULL!=p||!st.empty() ) { while ( NULL!=p ) { st.push( p ); p=p->lchild; } p=st.top(); if ( NULL==p->rchild||have_visited==p->rchild ) { Visit( p->data ); st.pop(); have_visited=p; p=NULL; } else { p=p->rchild; } } return OK; } int main() { BiTree newBiT; CreateBiTree( newBiT ); printf( "先序遍历结果\n" ); PreOrderTraverse( newBiT,Visit ); printf( "\n中序遍历结果\n" ); InOrderTraverse( newBiT,Visit ); printf( "\n后序遍历结果\n" ); PostOrderTraverse( newBiT,Visit ); printf( "\n---非递归中根---\n" ); InOrderTraverseNoDG( newBiT,Visit ); printf( "\n---非递归先根---\n" ); PreOrderTraverseNoDG( newBiT,Visit ); printf( "\n---非递归后根---\n" ); PostOrderTraverseNoDG( newBiT,Visit ); return 0; }