二叉树:一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
特点: 1、每个节点最多有两颗子树 2、二叉树是有序树,即左右子树的顺序不能颠倒
数据结构种的二叉树:(5种)
特殊的二叉树: 满二叉树、完全二叉树、平衡二叉树
存储结构: 顺序(只适用于完全二叉树---堆)、 链式两种存储方式
三种遍历方式:前序(根、左、右)、中序(左、根、右)、后序(左、右、根)
接口实现
#pragma once
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
typedef char DataType;
typedef struct BTNode {
char value;
struct BTNode* left; // 左孩子,同时代表着整棵左子树
struct BTNode* right; // 右孩子,同时代表着整棵右子树
} BTNode;
typedef struct {
BTNode* btNode; // 创建出树的根节点
int used; // 使用了的节点个数
} Result; // 创建二叉树的结构体返回值
BTNode* Create(DataType value);
Result CreateTree(DataType* preorder, int size);
void Preorder(BTNode* root);
void Inorder(BTNode* root);
void Postorder(BTNode* root);
int Size(BTNode* root);
int leafSize(BTNode* root);
int Height(BTNode* root);
int KLevelSize(BTNode* root, int k);
BTNode* Find(BTNode* root, DataType value);
int isSame(BTNode* p, BTNode* q);
int isSymmetric(BTNode* root);
int isSubTree(BTNode* p, BTNode* q);
#include "BinaryTree.h"
// 前序遍历
void Preorder(BTNode* root) {
if (root == NULL) {
return;
} // 树不存在
printf("%c ", root->value); // 根
Preorder(root->left); // 左子树
Preorder(root->right); // 右子树
}
void Inorder(BTNode* root){
if (root == NULL) {
return;
}
Inorder(root->left); // 左子树
printf("%c ", root->value); // 根
Inorder(root->right); // 右子树
}
void Postorder(BTNode* root) {
if (root == NULL) {
return;
}
Postorder(root->left); // 左子树
Postorder(root->right); // 右子树
printf("%c ", root->value); // 根
}
// 遍历的方式
//int count = 0;
//void Size(BTNode* root) {
// if (root == NULL) {
// return;
// }
// count++;
// Size(root->left);
// Size(root->right);
//}
// 递推的方式
int Size(BTNode* root) {
if (root == NULL) {
return 0;
}
int left = Size(root->left); // 左子树的节点总数
int right = Size(root->right); // 右子树的节点总数
return left + right + 1;
}
// 求叶子节点个数
int leafSize(BTNode* root) {
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 1;
} // 左右孩子都为空表示叶子节点
int left = leafSize(root->left);
int right = leafSize(root->right);
return left + right;
}
// 高度
int Height(BTNode* root) {
if (root == NULL) {
return 0;
}
int left = Height(root->left);
int right = Height(root->right);
return (left > right ? left : right) + 1;
}
int KLevelSize(BTNode* root, int k) {
if (root == NULL) {
return 0;
}
if (k == 1) {
return 1;
}
int left = KLevelSize(root->left, k - 1);
int right = KLevelSize(root->right, k - 1);
return left + right;
}
BTNode* Find(BTNode* root, DataType value) {
if (root == NULL) {
return NULL;
}
if (root->value == value) {
return root;
}
BTNode* result = Find(root->left, value); // 在左子树中找
if ( result != NULL) {
return result;
}
return Find(root->right, value);
/*
result = Find(root->right, value); // 在右子树中找
if (result != NULL) {
return result;
}
return NULL;
*/
}
int isSame(BTNode* p, BTNode* q) {
if (p == NULL && q == NULL) {
return 1;
}
if (p == NULL || q == NULL) {
return 0;
}
return (p->value == q->value) && isSame(p->left, q->left) && isSame(p->right, q->right);
}
// 判断两个树是否对称
int _isMirror(BTNode* p, BTNode* q) {
if (p == NULL && q== NULL) {
return 1;
}
if (p == NULL || q == NULL) {
return 0;
}
return p->value == q->value && _isMirror(p->left, q->right) && _isMirror(p->right, q->left);
}
// 判断某个树是否为镜像树, 左右子树对称
int isSymmetric(BTNode* root) {
if (root == NULL) {
return 1;
}
return _isMirror(root->left, root->right);
}
// 判断q是否为p的子树
int preorder(BTNode* r, BTNode* s) {
if (r == NULL) {
return 0;
}
if (isSame(r, s)) {
return 1;
}
int result = preorder(r->left, s);
if (result) { // 找到了
return result;
}
return preorder(r->right, s);
/*
result = preorder(r->right, s);
return result;
*/
}
int isSubTree(BTNode* p, BTNode* q) {
return preorder(p, q);
}
// 创建一个二叉节点
BTNode* Create(DataType value) {
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL) {
printf("动态内存分配失败");
return NULL;
}
node->value = value;
node->left = node->right = NULL;
return node;
}
// 根据前序遍历构建二叉树
Result CreateTree(DataType* preorder, int size) {
if (size == 0) {
Result r = { NULL, 0 };
return r;
}
if (preorder[0] == '#') {
Result r = { NULL, 1 };
return r;
}
BTNode* root = (BTNode*)malloc(sizeof(BTNode));
if (root == NULL) {
printf("内存分配失败");
Result r = { NULL, -1 };
return r;
}
root->value = preorder[0];
Result left = CreateTree(preorder + 1, size - 1);
root->left = left.btNode;
Result right = CreateTree(preorder + 1 + left.used, size - 1 - left.used);
root->right = right.btNode;
Result r = { root, 1 + left.used + right.used };
return r;
}
#include "BinaryTree.h"
int main() {
char arr[] = "ABD##E#H##CF##G";
int len = strlen(arr);
Result r = CreateTree(arr, len);
int b = r.btNode->value;
/*BTNode* res = Search(a, 'K');
printf(" 高度: %d", Height(a));
printf(" 节点个数: %d", Size(a));
printf(" 叶子节点个数: %d", leafSize(a));
printf(" 第k层节点个数: %d", KLevelSize(a, 4));*/
return 0;
}