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; }
分类:
C/C++
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!