目录
二叉树定义
二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。
特殊类型
满二叉树
如果一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树 。
完全二叉树
深度为k,有n个节点的二叉树当且仅当其每一个节点都与深度为k的满二叉树中编号从1到n的节点一一对应时,称为完全二叉树 。
完全二叉树的特点是叶子节点只可能出现在层序最大的两层上,并且某个节点的左分支下子孙的最大层序与右分支下子孙的最大层序相等或大1 。
代码实现
定义二叉树
typedef char ElemType;
typedef struct BinaryTree {
ElemType val; //值
struct BinaryTree* left; //左子树
struct BinaryTree* right; //右子树
}BinaryTree;
前序遍历创建二叉树
/// <summary>
/// 创建二叉树
/// </summary>
/// <param name="str">对应的序列</param>
/// <param name="pi">指向下标的指针</param>
/// <param name="n">序列的长度</param>
/// <returns>返回创建的树</returns>
BinaryTree* Create(const char* str, int* pi, int n) {
if (*pi >= n || str[*pi] == '#') {
++* pi;
return NULL;
}
BinaryTree* root = (BinaryTree*)malloc(sizeof(BinaryTree));
assert(root);
root->val = str[*pi];
++* pi;
root->left = Create(str, pi, n);
root->right = Create(str, pi, n);
return root;
}
前序遍历
void PreOrder(BinaryTree* root) {
if (!root) {
printf("null ");
return;
}
printf("%c ", root->val);
PreOrder(root->left);
PreOrder(root->right);
}
中序遍历
void InOrder(BinaryTree* root) {
if (!root) {
printf("null ");
return;
}
PreOrder(root->left);
printf("%c ", root->val);
PreOrder(root->right);
}
后序遍历
void PostOrder(BinaryTree* root) {
if (!root) {
printf("null ");
return;
}
PreOrder(root->left);
PreOrder(root->right);
printf("%c ", root->val);
}
获取树的深度
int Depth(BinaryTree* root) {
if (!root) {
return 0;
}
int left = Depth(root->left);
int right = Depth(root->right);
int high = left > right ? left : right;
return high + 1;
}
获取叶节点的个数
int CountOfLeves(BinaryTree* root) {
if (!root) {
return 0;
}
if (!root->left && !root->right) {
return 1;
}
return CountOfLeves(root->left) + CountOfLeves(root->right);
}
判断满二叉树
对于满二叉树,其深度和叶节点符合2的深度减1次方等于叶节点的个数
bool IsFull(BinaryTree* root) {
int depth = Depth(root);
int leves = Depth(root);
return pow(2, depth - 1) == leves;
}
判断对称二叉树
对称二叉树:
从父节点将左右节点分开,左右节点相互对称
bool isSame(BinaryTree* left, BinaryTree* right) {
if (!left && !right) {
return true;
}
if (!left || !right) {
return false;
}
if (left->val == right->val) {
return isSame(left->right, right->left) && isSame(left->left, right->right);
}
return false;
}
bool IsSymmetic(BinaryTree* root) {
if (!root) {
return true;
}
return isSame(root->left, root->right);
}
在树中查找值为val的结点
BinaryTree* FindTree(BinaryTree* root, ElemType val) {
if (!root) {
return NULL;
}
if (root->val == val) {
return root;
}
BinaryTree* tmp = FindTree(root->left, val);
if (tmp != NULL) {
return tmp;
}
tmp = FindTree(root->right, val);
if (tmp != NULL) {
return tmp;
}
return NULL;
}
整体代码
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <math.h>
typedef char ElemType;
typedef struct BinaryTree {
ElemType val; //值
struct BinaryTree* left; //左子树
struct BinaryTree* right; //右子树
}BinaryTree;
/// <summary>
/// 创建二叉树
/// </summary>
/// <param name="str">对应的序列</param>
/// <param name="pi">指向下标的指针</param>
/// <param name="n">序列的长度</param>
/// <returns>返回创建的树</returns>
BinaryTree* Create(const char* str, int* pi, int n) {
if (*pi >= n || str[*pi] == '#') {
++* pi;
return NULL;
}
BinaryTree* root = (BinaryTree*)malloc(sizeof(BinaryTree));
assert(root);
root->val = str[*pi];
++* pi;
root->left = Create(str, pi, n);
root->right = Create(str, pi, n);
return root;
}
//前序遍历
void PreOrder(BinaryTree* root) {
if (!root) {
printf("null ");
return;
}
printf("%c ", root->val);
PreOrder(root->left);
PreOrder(root->right);
}
//中序遍历
void InOrder(BinaryTree* root) {
if (!root) {
printf("null ");
return;
}
PreOrder(root->left);
printf("%c ", root->val);
PreOrder(root->right);
}
//后序遍历
void PostOrder(BinaryTree* root) {
if (!root) {
printf("null ");
return;
}
PreOrder(root->left);
PreOrder(root->right);
printf("%c ", root->val);
}
//树的深度
int Depth(BinaryTree* root) {
if (!root) {
return 0;
}
int left = Depth(root->left);
int right = Depth(root->right);
int high = left > right ? left : right;
return high + 1;
}
//叶节点的个数
int CountOfLeves(BinaryTree* root) {
if (!root) {
return 0;
}
if (!root->left && !root->right) {
return 1;
}
return CountOfLeves(root->left) + CountOfLeves(root->right);
}
//判断是不是满二叉树
bool IsFull(BinaryTree* root) {
int depth = Depth(root);
int leves = Depth(root);
return pow(2, depth - 1) == leves;
}
bool isSame(BinaryTree* left, BinaryTree* right) {
if (!left && !right) {
return true;
}
if (!left || !right) {
return false;
}
if (left->val == right->val) {
return isSame(left->right, right->left) && isSame(left->left, right->right);
}
return false;
}
//判断是否是对称二叉树
bool IsSymmetic(BinaryTree* root) {
if (!root) {
return true;
}
return isSame(root->left, root->right);
}
BinaryTree* FindTree(BinaryTree* root, ElemType val) {
if (!root) {
return NULL;
}
if (root->val == val) {
return root;
}
BinaryTree* tmp = FindTree(root->left, val);
if (tmp != NULL) {
return tmp;
}
tmp = FindTree(root->right, val);
if (tmp != NULL) {
return tmp;
}
return NULL;
}