二叉树先/中/后序的递归遍历

二叉树的先中后序的遍历方法就不多说了,根左右,左根右以及左右根。

我们今天讨论递归遍历,拿先序遍历举例。

首先讲一些预备知识。二叉树从一开始算节点,如果某一结点的位置为i,那么它的左右孩子节点分别为2*i ,2*i+1 ,他的双亲节点为 i/2 向下取整。

然后我们就可以开始使用递归读取二叉树。

输入一棵二叉树,为 

7

1 2 3 0 0 0 0

我们先读根节点,然后再读根节点下左子树

接着读左子树的根节点,使用递归,知道节点数为0,我们开始读右节点

代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h> 
#include <string.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 15 /* 存储空间初始分配量 */
#define MAX_TREE_SIZE 15 /* 二叉树的最大结点数 */

typedef int Status;		/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int TElemType;  /* 树结点的数据类型,目前暂定为整型 */
typedef TElemType SqBiTree[MAX_TREE_SIZE]; /* 0号单元存储根结点  */

typedef struct
{
	int level,order; /* 结点的层,本层序号(按满二叉树计算) */
}Position;

TElemType Nil=0; /*  设整型以0为空 */

int nArray[15];

//--------------------------------------------------------------- 
/* 初始条件: 二叉树存在 */
/* 操作结果: 先序遍历T。 */
Status PreOrderTraverse(SqBiTree T, int e)
{ 
    /********************begin*******************/
    printf("%d ",T[e]);
    if(T[2*e+1]!=Nil) {PreOrderTraverse(T,2*e+1);}
    if(T[2*e+2]!=Nil) {PreOrderTraverse(T,e*2+2);}
    /*********************end********************/	
}
/* 初始条件: 二叉树存在 */
/* 操作结果: 中序遍历T。 */
Status InOrderTraverse(SqBiTree T, int e)
{ 
    /********************begin*******************/
    
    if(T[2*e+1]!=Nil) {InOrderTraverse(T,2*e+1);}
    printf("%d ",T[e]);
    if(T[2*e+2]!=Nil) {InOrderTraverse(T,e*2+2);}
    /*********************end********************/	
}

/* 初始条件: 二叉树T存在 */
/* 操作结果: 后序遍历T。 */
Status PostOrderTraverse(SqBiTree T, int e)
{ 
    /********************begin*******************/
    
    if(T[2*e+1]!=Nil) {PostOrderTraverse(T,2*e+1);}
    if(T[2*e+2]!=Nil) {PostOrderTraverse(T,e*2+2);}
    printf("%d ",T[e]);
    /*********************end********************/	
}
int main()
{
	SqBiTree T;
	int i,n; scanf("%d",&n);	
	int tmp; 
	for (i = 0; i < n; i++){
		scanf("%d",&tmp);
		T[i]=tmp;
	}
	for (; i < MAX_TREE_SIZE; i++)
		T[i]=0;	
	printf("先序遍历二叉树:");
	PreOrderTraverse(T, 0);
	printf("\n中序遍历二叉树:");
	InOrderTraverse(T, 0);
	printf("\n后序遍历二叉树:");
	PostOrderTraverse(T, 0);
	return 0;
}

  

二叉树二叉链表存储结构定义如下: ```c typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; } BiTNode, *BiTree; ``` 其,data 表示结点的据项,lchild 和 rchild 分别指向左右子树。 二叉树的创建可以采用递归方式,输入根结点,然后递归输入左右子树。 ```c void createBiTree(BiTree *T) { int data; scanf("%d", &data); if (data == -1) { *T = NULL; } else { *T = (BiTree) malloc(sizeof(BiTNode)); (*T)->data = data; createBiTree(&((*T)->lchild)); createBiTree(&((*T)->rchild)); } } ``` 二叉树序/序/后序递归遍历可以采用类似的递归方式,分别遍历根结点,然后递归遍历左右子树。 ```c // 先序遍历 void preOrder(BiTree T) { if (T != NULL) { printf("%d ", T->data); preOrder(T->lchild); preOrder(T->rchild); } } // 遍历 void inOrder(BiTree T) { if (T != NULL) { inOrder(T->lchild); printf("%d ", T->data); inOrder(T->rchild); } } // 后序遍历 void postOrder(BiTree T) { if (T != NULL) { postOrder(T->lchild); postOrder(T->rchild); printf("%d ", T->data); } } ``` 统计二叉树的高度可以采用递归方式,左右子树的高度取最大值并加 1。 ```c int getDepth(BiTree T) { if (T == NULL) { return 0; } else { int leftDepth = getDepth(T->lchild); int rightDepth = getDepth(T->rchild); return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1; } } ``` 统计各类结点的个同样可以采用递归方式,分别统计根结点、左子树、右子树的结点个。 ```c int getNodeNum(BiTree T) { if (T == NULL) { return 0; } else { return getNodeNum(T->lchild) + getNodeNum(T->rchild) + 1; } } int getLeafNum(BiTree T) { if (T == NULL) { return 0; } else if (T->lchild == NULL && T->rchild == NULL) { return 1; } else { return getLeafNum(T->lchild) + getLeafNum(T->rchild); } } int getSingleNum(BiTree T) { if (T == NULL) { return 0; } else if ((T->lchild == NULL && T->rchild != NULL) || (T->lchild != NULL && T->rchild == NULL)) { return getSingleNum(T->lchild) + getSingleNum(T->rchild) + 1; } else { return getSingleNum(T->lchild) + getSingleNum(T->rchild); } } ``` 序/序非递归遍历采用栈来实现。先序遍历时,将根结点入栈,然后弹出栈顶结点并输出其值,如果该结点有右子树,则将其右子树入栈;如果该结点有左子树,则将其左子树入栈。遍历时,将根结点入栈,然后将其左子树全部入栈,再弹出栈顶结点并输出其值,最后将其右子树入栈。 ```c // 序非递归遍历 void preOrderNonRecursive(BiTree T) { if (T == NULL) { return; } BiTree stack[MAXSIZE]; int top = -1; stack[++top] = T; while (top != -1) { BiTree node = stack[top--]; printf("%d ", node->data); if (node->rchild != NULL) { stack[++top] = node->rchild; } if (node->lchild != NULL) { stack[++top] = node->lchild; } } } // 序非递归遍历 void inOrderNonRecursive(BiTree T) { if (T == NULL) { return; } BiTree stack[MAXSIZE]; int top = -1; BiTree node = T; while (node != NULL || top != -1) { while (node != NULL) { stack[++top] = node; node = node->lchild; } if (top != -1) { node = stack[top--]; printf("%d ", node->data); node = node->rchild; } } } ``` 层序遍历采用队列来实现。将根结点入队,然后每次弹出队首结点并输出其值,如果该结点有左子树,则将其左子树入队;如果该结点有右子树,则将其右子树入队。 ```c void levelOrder(BiTree T) { if (T == NULL) { return; } BiTree queue[MAXSIZE]; int front = 0, rear = 0; queue[rear++] = T; while (front != rear) { BiTree node = queue[front++]; printf("%d ", node->data); if (node->lchild != NULL) { queue[rear++] = node->lchild; } if (node->rchild != NULL) { queue[rear++] = node->rchild; } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值