前面一篇文章单独说了二叉树的构建,二叉树构建好后,接下来就有二叉树的遍历问题,即读出二叉树中所有的节点数据。
三种遍历方法:前序遍历,中序遍历,后序遍历。
前序遍历:先访问根节点,然后前序遍历左子树,最后前序遍历右子树
中序遍历:先中序遍历左子树,然后访问根节点,最后中序遍历右子树
后续遍历:先后序遍历左子树,然后后序遍历右子树,最后访问根节点
由上面的遍历步骤可以看出三者的差别就是根节点访问顺序的不同。
如果将递归方式构建二叉树的过程理清楚了,那么二叉树的遍历问题就比较容易理解。这里使用最容易理解的递归方法遍历二叉树,代码如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<malloc.h> 4 5 //定义二叉树 6 typedef struct node{ 7 int data;//数据元素 8 struct node *left;//指向左子树 9 struct node *right;//指向右子树 10 }BTree; 11 12 //构造二叉树:递归方式 13 int BTreeCreate(BTree **tp) 14 { 15 //构造方法,或者说构造顺序:从左子树开始构造 16 int x; 17 scanf("%d",&x); 18 if(x<=0) 19 { 20 *tp=NULL;//指针为空,树节点中的某个指针为空 21 return 0; 22 } 23 *tp=(BTree*)malloc(sizeof(BTree));//将树节点中指针指向该地址空间 24 if(tp==NULL) 25 return 0; 26 (*tp)->data=x; 27 BTreeCreate(&((*tp)->left)); 28 BTreeCreate(&((*tp)->right)); 29 return 1; 30 } 31 32 //遍历:前序遍历,递归的方式,先根节点,再左子树后右子树 33 void PreOrder(BTree *tree) 34 { 35 if(tree==NULL) 36 { 37 return; 38 } 39 printf("%d ",tree->data); 40 PreOrder(tree->left); 41 PreOrder(tree->right); 42 } 43 44 //遍历:中序遍历,递归方式,先左子树再根节点最后右子树 45 void MidOrder(BTree *tree) 46 { 47 if(tree==NULL) 48 { 49 return; 50 } 51 MidOrder(tree->left); 52 printf("%d ",tree->data); 53 MidOrder(tree->right); 54 } 55 56 //遍历:后序遍历,递归方式,先左子树再右子树最后根节点 57 58 void PostOrder(BTree *tree) 59 { 60 if(tree==NULL) 61 { 62 return; 63 } 64 PostOrder(tree->left); 65 PostOrder(tree->right); 66 printf("%d ",tree->data); 67 } 68 69 int main() 70 { 71 //二叉树构建 72 BTree *tree; 73 printf("Create binary tree:\n"); 74 BTreeCreate(&tree); 75 //前序遍历 76 printf("Pre order:\n"); 77 PreOrder(tree); 78 printf("\n"); 79 //中序遍历 80 printf("Mid order:\n"); 81 MidOrder(tree); 82 printf("\n"); 83 //后序遍历 84 printf("Post order:\n"); 85 PostOrder(tree); 86 printf("\n"); 87 88 return 0; 89 }
测试:如下的二叉树
依次输入:1,2,3,0,0,4,0,0,6,7,0,0,0
测试结果如下: