二叉树四种遍历方式-先序/中序/后序/层序

以先序方式创建一颗二叉树:
创建一棵图形如下的二叉树

// 示例二叉树
         a
       /   \
      b      c
       \      \
        d      e
       /
      f

代码示例:

/* 遍历二叉树 【先序、中序、后序、层次遍历】*/
#include <stdio.h>
#include <stdlib.h>

// 定义二叉树结构体 
typedef struct Bnode {
	char data;
	struct Bnode *lchild;
	struct Bnode *rchild;
} Bnode,*Btree;

// 创建二叉树(按先序顺序输入二叉树)
Btree Creat(Btree T) {
	//手动输入的二叉树按先序顺序输入
	char ch;
	printf("Enter the data of node:");
	scanf(" %c",&ch);
	if(ch != '#') { // 输入#表示结点为空
		T = (Btree)malloc(sizeof(Bnode));
		T->data = ch;
		T->lchild = NULL;
		T->rchild = NULL;
		T->lchild = Creat(T->lchild);
		T->rchild = Creat(T->rchild);
	}
	return T;
}
// 先序
void PreOrder(Btree T) {
	if(T==NULL)
		return;
	printf("%c ",T->data);
	PreOrder(T->lchild);
	PreOrder(T->rchild);
}
// 中序
void InOrder(Btree T) {
	if(T==NULL)
		return;
	InOrder(T->lchild);
	printf("%c ",T->data);
	InOrder(T->rchild);
}
// 后序
void PostOrder(Btree T) {
	if(T==NULL)
		return;
	PostOrder(T->lchild);
	PostOrder(T->rchild);
	printf("%c ",T->data);
}
//层序
void LevelOrder(Btree T) {
	if(T==NULL)
		return;
	int front = -1,rear = -1;
	Btree p;
	Btree Queue[30]; // 定义一个队列,大小暂时取30
	Queue[++rear] = T; // 根节点入队
	while(front<rear) { // 队列不为空
		p = Queue[++front]; // 队首元素出队
		printf("%c ",p->data); // 打印结点元素
		if(p->lchild!=NULL) // 左孩子不为空则入队
			Queue[++rear] = p->lchild;
		if(p->rchild!=NULL) // 右孩子不为空则入队
			Queue[++rear] = p->rchild;
	}
}
//销毁二叉树
void Destroy(Btree T) {
	if(T==NULL)
		return;
	else if(T->lchild==NULL&&T->rchild==NULL) {
		free(T);
		return;
	} else {
		Destroy(T->lchild);
		Destroy(T->rchild);
	}
}
void main() {
	Btree T = NULL; // 定义二叉树头结点
	T = Creat(T); // 生成二叉树
	if(!T)
		return;
	printf("\n先序序列:");
	PreOrder(T);
	printf("\n中序序列:");
	InOrder(T);
	printf("\n后序序列:");
	PostOrder(T);
	printf("\n层次遍历:");
	LevelOrder(T);
	printf("\n");
	Destroy(T);
	printf("\n二叉树已销毁!\n");
}

结果示例:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值