本文代码基于【数据结构】【严蔚敏】【清华大学】
包含了大多数二叉树的基本操作
1.准备部分的代码:
用c++其实就是用了个max()函数
#include <stdio.h>
#include <stdlib.h>//malloc和exit函数所需头文件
#include <iostream>
using namespace std;
#define MaxSize 100
typedef char ElemType;
当然也可以改成C,记得加上一个自定义max函数
#include <stdio.h>
#include <stdlib.h>//malloc和exit函数所需头文件
#define MaxSize 100
typedef char ElemType;
int max(int a,int b)
{
return a>b?a:b;
}
2.构造二叉树结点
包括数据域和左右孩子指针
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild; // 左右孩子指针
} BiTNode, *BiTree;
3.先序输入二叉树中结点的值
一些必要的注解:
①TheBinaryTree为结构体指针,指向结构体
BiTree TheBinaryTree=BiTNode *TheBinaryTree
②T为TheBinaryTree的引用,是结构体指针
BiTree &T= BiTNode *&T
③BT是结构指针TheBinaryTree的指针,BT指向结构体指针
BiTNode **BT=BiTree *BT
所有有两种 CreateBiTree写法:
void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T
{
// 按先序次序输入二叉树中结点的值
// 构造二叉链表表示的二叉树T。
ElemType ch;
static int i = 0;
char pch[] = "ABC$$DE$G$$F$$$"; // 欲产生的 先序序列。图6.8(b)
ch = pch[i++];
if(ch == '$') // 空树
T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
if(!T) // 检测是否申请结点成功
exit(-1);
T->data = ch; // 生成根结点
CreateBiTree(T->lchild); // 构造左子树
CreateBiTree(T->rchild); // 构造右子树
}
}
void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此时为指针的指针, BiTNode* *BT==BiTree *BT
{
// 按先序次序输入二叉树中结点的值
// 构造二叉链表表示的二叉树BT。
ElemType ch;
static int i = 0;
char pch[] = "AB D C "; // 欲产生的二叉树 先序序列
ch = pch[i++];
//scanf("%c",&ch);
if(ch == ' ') // 空树
*BT = NULL;
else {
*BT = (BiTree)malloc(sizeof(BiTNode));
if(!*BT) // 检测是否申请结点成功
exit(-1);
(*BT)->data = ch; // 生成根结点
CreateBiTree_Pointer(&(*BT)->lchild); // 构造左子树
CreateBiTree_Pointer(&(*BT)->rchild); // 构造右子树
}
}
4.三种遍历(递归)
// 中序遍历
void InOrderTraversal(BiTree BT)
{
if(BT) {
InOrderTraversal(BT->lchild);
printf("%c ", BT->data);
InOrderTraversal(BT->rchild);
}
}
//先序遍历
void PreOrderTraversal(BiTree BT)
{
if(BT) {
printf("%c ", BT->data);
PreOrderTraversal(BT->lchild);
PreOrderTraversal(BT->rchild);
}
}
// 后序遍历
void PostOrderTraversal(BiTree BT)
{
if(BT) {
PostOrderTraversal(BT->lchild);
PostOrderTraversal(BT->rchild);
printf("%c ", BT->data);
}
}
5.中序遍历非递归遍历算法(关于其他遍历算法之后还会写文章提到)
// 中序遍历非递归遍历算法
//利用压栈
void InOrderTraversal_NoRecursion(BiTNode *T)
{
BiTNode *Stack[MaxSize];//BiTree Stack[MaxSize]
int top = -1;
while(T || (top != -1)) {
while(T) { // 一直向左并将沿途结点压入堆栈
Stack[++top] = T;
T = T->lchild;
}
if(top != -1) {
T = Stack[top--]; // 结点弹出堆栈
printf("%c ", T->data); //(访问)打印结点
T = T->rchild; // 转向右子树
}
}
}
6.输出叶子结点值
// 输出二叉树中的叶子结点。
void PreOrderPrintLeaves(BiTree BT)
{
if(BT) {
if(BT->lchild == NULL && BT->rchild == NULL)
printf("%c ", BT->data);
PreOrderPrintLeaves(BT->lchild);
PreOrderPrintLeaves(BT->rchild);
}
}
7.输出深度
// 求二叉树的深度
int Binary_tree_Deepness(BiTNode *T)
{
if(T == NULL)
return 0;
else
if(T->lchild == NULL && T->rchild == NULL)
return 1;
else
return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild));
}
//表示形式2
int Binary_tree_Deepness_Post(BiTNode *T)
{
int h1, h2;
if(T == NULL)
return 0;
h1 = Binary_tree_Deepness_Post(T->lchild);
h2 = Binary_tree_Deepness_Post(T->rchild);
if(T->lchild == NULL && T->rchild == NULL)
return 1;
else
return 1 + max(h1, h2);
}
8.求度为 2 的结点数
//求二叉树的度为 2 的结点数算法
int BT_CountDegree2(BiTNode *T)
{
int n1, n2;
if (T == NULL)
return 0;
else {
n1 = BT_CountDegree2(T->lchild);
n2 = BT_CountDegree2(T->rchild);
if (T->lchild != NULL && T->rchild != NULL)
return 1 + n1 + n2;
else
return n1 + n2;
}
}
9.构造和销毁
PS:完整代码中没用到构造和销毁,Init某种意义上可有可无,destroy最好还是加一下
Status InitBiTree(BiTree &T)
{
// 操作结果: 构造空二叉树T
T = NULL;
return OK;
}
void DestroyBiTree(BiTree &T)
{
// 初始条件: 二叉树T存在。操作结果: 销毁二叉树T
if(T) { // 非空树
if(T->lchild) // 有左孩子
DestroyBiTree(T->lchild); // 销毁左孩子子树
if(T->rchild) // 有右孩子
DestroyBiTree(T->rchild); // 销毁右孩子子树
free(T); // 释放根结点
T = NULL; // 空指针赋0
}
}
10.主函数
int main()
{
BiTree TheBinaryTree;//BiTNode *TheBinaryTree
printf("
建立二叉树,请输入结点值系列:
");
CreateBiTree(TheBinaryTree);//TheBinaryTree为结构体指针
printf("
先序遍历序列:
");
PreOrderTraversal(TheBinaryTree);
printf("
中序遍历序列:
");
InOrderTraversal(TheBinaryTree);
printf("
中序遍历序列 - 中序遍历非递归算法:
");
InOrderTraversal_NoRecursion(TheBinaryTree);
printf("
后序遍历序列:
");
PostOrderTraversal(TheBinaryTree);
printf("
二叉树的深度为:
");
//printf("%d",Binary_tree_Deepness_Post(TheBinaryTree));
printf("%d", Binary_tree_Deepness(TheBinaryTree));
printf("
叶子结点为:
");
PreOrderPrintLeaves(TheBinaryTree);
printf("
度为2的结点个数为:
");
printf("%d", BT_CountDegree2(TheBinaryTree));
return 1;
}
便于复制完整源代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define MaxSize 100
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild; // 左右孩子指针
} BiTNode, *BiTree;
//TheBinaryTree为结构体指针,指向结构体
//BiTree TheBinaryTree==BiTNode *TheBinaryTree
//BiTree &T== BiTNode* &T T为TheBinaryTree的引用,是结构体指针
//BiTNode **BT==BiTree *BT BT是结构指针TheBinaryTree的指针, BT指向结构体指针
void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T
{
// 按先序次序输入二叉树中结点的值
// 构造二叉链表表示的二叉树T。
ElemType ch;
static int i = 0;
char pch[] = "ABC$$DE$G$$F$$$"; // 欲产生的 先序序列。图6.8(b)
ch = pch[i++];
if(ch == '$') // 空树
T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
if(!T) // 检测是否申请结点成功
exit(-1);
T->data = ch; // 生成根结点
CreateBiTree(T->lchild); // 构造左子树
CreateBiTree(T->rchild); // 构造右子树
}
}
void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此时为指针的指针, BiTNode* *BT==BiTree *BT
{
// 按先序次序输入二叉树中结点的值
// 构造二叉链表表示的二叉树BT。
ElemType ch;
static int i = 0;
char pch[] = "AB D C "; // 欲产生的二叉树 先序序列
ch = pch[i++];
//scanf("%c",&ch);
if(ch == ' ') // 空树
*BT = NULL;
else {
*BT = (BiTree)malloc(sizeof(BiTNode));
if(!*BT) // 检测是否申请结点成功
exit(-1);
(*BT)->data = ch; // 生成根结点
CreateBiTree_Pointer(&(*BT)->lchild); // 构造左子树
CreateBiTree_Pointer(&(*BT)->rchild); // 构造右子树
}
}
// 中序遍历
void InOrderTraversal(BiTree BT)
{
if(BT) {
InOrderTraversal(BT->lchild);
printf("%c ", BT->data);
InOrderTraversal(BT->rchild);
}
}
//先序遍历
void PreOrderTraversal(BiTree BT)
{
if(BT) {
printf("%c ", BT->data);
PreOrderTraversal(BT->lchild);
PreOrderTraversal(BT->rchild);
}
}
// 后序遍历
void PostOrderTraversal(BiTree BT)
{
if(BT) {
PostOrderTraversal(BT->lchild);
PostOrderTraversal(BT->rchild);
printf("%c ", BT->data);
}
}
// 中序遍历非递归遍历算法
//利用压栈
void InOrderTraversal_NoRecursion(BiTNode *T)
{
BiTNode *Stack[MaxSize];//BiTree Stack[MaxSize]
int top = -1;
while(T || (top != -1)) {
while(T) { // 一直向左并将沿途结点压入堆栈
Stack[++top] = T;
T = T->lchild;
}
if(top != -1) {
T = Stack[top--]; // 结点弹出堆栈
printf("%c ", T->data); //(访问)打印结点
T = T->rchild; // 转向右子树
}
}
}
// 输出二叉树中的叶子结点。
void PreOrderPrintLeaves(BiTree BT)
{
if(BT) {
if(BT->lchild == NULL && BT->rchild == NULL)
printf("%c ", BT->data);
PreOrderPrintLeaves(BT->lchild);
PreOrderPrintLeaves(BT->rchild);
}
}
// 求二叉树的深度
int Binary_tree_Deepness(BiTNode *T)
{
if(T == NULL)
return 0;
else
if(T->lchild == NULL && T->rchild == NULL)
return 1;
else
return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild));
}
int Binary_tree_Deepness_Post(BiTNode *T)
{
int h1, h2;
if(T == NULL)
return 0;
h1 = Binary_tree_Deepness_Post(T->lchild);
h2 = Binary_tree_Deepness_Post(T->rchild);
if(T->lchild == NULL && T->rchild == NULL)
return 1;
else
return 1 + max(h1, h2);
}
//求二叉树的度为 2 的结点数算法
int BT_CountDegree2(BiTNode *T)
{
int n1, n2;
if (T == NULL)
return 0;
else {
n1 = BT_CountDegree2(T->lchild);
n2 = BT_CountDegree2(T->rchild);
if (T->lchild != NULL && T->rchild != NULL)
return 1 + n1 + n2;
else
return n1 + n2;
}
}
int main()
{
BiTree TheBinaryTree;//BiTNode *TheBinaryTree
printf("
建立二叉树,请输入结点值系列:
");
CreateBiTree(TheBinaryTree);//TheBinaryTree为结构体指针
printf("
先序遍历序列:
");
PreOrderTraversal(TheBinaryTree);
printf("
中序遍历序列:
");
InOrderTraversal(TheBinaryTree);
printf("
中序遍历序列 - 中序遍历非递归算法:
");
InOrderTraversal_NoRecursion(TheBinaryTree);
printf("
后序遍历序列:
");
PostOrderTraversal(TheBinaryTree);
printf("
二叉树的深度为:
");
//printf("%d",Binary_tree_Deepness_Post(TheBinaryTree));
printf("%d", Binary_tree_Deepness(TheBinaryTree));
printf("
叶子结点为:
");
PreOrderPrintLeaves(TheBinaryTree);
printf("
度为2的结点个数为:
");
printf("%d", BT_CountDegree2(TheBinaryTree));
return 1;
}