#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef char DataType;
typedef struct BTreeNode {
struct BTreeNode *pLeft;
struct BTreeNode *pRight;
DataType data;
} BTreeNode;
BTreeNode * CreateNode(DataType data)
{
BTreeNode *pNode = (BTreeNode *)malloc(sizeof(BTreeNode));
assert(pNode != NULL);
pNode->pLeft = pNode->pRight = NULL;
pNode->data = data;
return pNode;
}
BTreeNode * CreateTree(DataType pre[], int size, int *index)
{
// 判断条件
// 1 越界;2 == #
if (*index >= size) {
return NULL;
}
if (pre[*index] == '#') {
(*index)++;
return NULL;
}
BTreeNode *pRoot = CreateNode(pre[*index]);
(*index)++;
pRoot->pLeft = CreateTree(pre, size, index);
pRoot->pRight = CreateTree(pre, size, index);
return pRoot;
}
int GetHeightR(BTreeNode *pRoot)
{
if (pRoot == NULL) {
return 0;
}
int left = GetHeightR(pRoot->pLeft);
int right = GetHeightR(pRoot->pRight);
return (left > right ? left : right) + 1;
}
void GetHeight(BTreeNode *pRoot, int *pHeight)
{
if (pRoot == NULL) {
*pHeight = 0;
return;
}
int left, right;
GetHeight(pRoot->pLeft, &left);
GetHeight(pRoot->pRight, &right);
*pHeight = (left > right ? left : right) + 1;
}
int MAX(int a, int b, int c)
{
if (a >= b && a >= c) {
return a;
}
if (b >= a && b >= c) {
return b;
}
return c;
}
int 找最远距离(BTreeNode *pRoot)
{
if (pRoot == NULL) {
return 0;
}
int leftHeight = GetHeightR(pRoot->pLeft);
int rightHeight = GetHeightR(pRoot->pRight);
int rootPath = leftHeight + rightHeight;
int leftPath = 找最远距离(pRoot->pLeft);
int rightPath = 找最远距离(pRoot->pRight);
return MAX(rootPath, leftPath, rightPath);
}
int 找最远距离优化版(BTreeNode *pRoot, int *pHeight)
{
if (pRoot == NULL) {
*pHeight = 0;
return 0;
}
int leftHeight, rightHeight;
int leftPath = 找最远距离优化版(pRoot->pLeft, &leftHeight);
int rightPath = 找最远距离优化版(pRoot->pRight, &rightHeight);
int rootPath = leftHeight + rightHeight;
*pHeight = (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
return MAX(rootPath, leftPath, rightPath);
}
void Mirror(BTreeNode *pRoot)
{
if (pRoot == NULL) {
return;
}
// 可加可不加(加了效率更好)
if (pRoot->pLeft == NULL && pRoot->pRight == NULL) {
return;
}
BTreeNode *pLeft = pRoot->pLeft;
pRoot->pLeft = pRoot->pRight;
pRoot->pRight = pLeft;
Mirror(pRoot->pLeft);
Mirror(pRoot->pRight);
}
int IsBalance(BTreeNode *pRoot)
{
if (pRoot == NULL) {
return 1;
}
int left = IsBalance(pRoot->pLeft);
if (left == 0) {
// 左子树不平衡
return 0;
}
int right = IsBalance(pRoot->pRight);
if (right == 0) {
// 右子树不平衡
return 0;
}
// 左右子树都平衡
int leftH = GetHeightR(pRoot->pLeft);
int rightH = GetHeightR(pRoot->pRight);
if (leftH - rightH >= -1 && leftH - rightH <= 1) {
return 1;
}
else {
return 0;
}
}
BTreeNode * Find(BTreeNode *pRoot, BTreeNode *node)
{
if (pRoot == NULL) {
return NULL;
}
if (pRoot == node) {
return pRoot;
}
BTreeNode *pFound = Find(pRoot->pLeft, node);
if (pFound != NULL) {
return pFound;
}
return Find(pRoot->pRight, node);
}
BTreeNode * 找最近公共祖先(BTreeNode *pRoot, BTreeNode *n1, BTreeNode *n2)
{
// 在左子树中找 n1
BTreeNode *pN1LeftFound = Find(pRoot->pLeft, n1);
// 在左子树中找 n2
BTreeNode *pN2LeftFound = Find(pRoot->pLeft, n2);
// 在右子树中找 n1
BTreeNode *pN1RightFound = Find(pRoot->pRight, n1);
// 在右子树中找 n2
BTreeNode *pN2RightFound = Find(pRoot->pRight, n2);
/* 四种情况
1. n1 和 n2 分别在一棵子树中
2. n1 和 n2 不在一棵子树中
3. n1 或者 n2 一个是根(pRoot),另一个在一棵子树中
4. n1 或者 n2 有一个没找到
*/
if (pN1LeftFound != NULL && pN2LeftFound != NULL) {
// n1 和 n2 都在左子树中
return 找最近公共祖先(pRoot->pLeft, n1, n2);
}
if (pN1RightFound != NULL && pN2RightFound != NULL) {
// n1 和 n2 都在右子树中
return 找最近公共祖先(pRoot->pRight, n1, n2);
}
if (pN1LeftFound != NULL && pN2RightFound != NULL) {
// n1 在左,n2 在右
return pRoot;
}
if (pN2LeftFound != NULL && pN1RightFound != NULL) {
// n1 在右,n2 在左
return pRoot;
}
if (n1 == pRoot && (pN2LeftFound || pN2RightFound)) {
// n1 是根,n2 在子树中
return pRoot;
}
if (n2 == pRoot && (pN1LeftFound || pN1RightFound)) {
// n2 是根,n1 在子树中
return pRoot;
}
return NULL;
}
BTreeNode * CreateTreeByPreOrderAndInOrder(
char preOrder[], int preOrderSize,
char inOrder[], int inOrderSize)
{
if (preOrderSize <= 0) {
return NULL;
}
char rootChar = preOrder[0]; // 这里越界了么?
int i;
for (i = 0; i < inOrderSize; i++) {
if (inOrder[i] == rootChar) {
break;
}
}
if (i == inOrderSize) {
// 没找到,出错
assert(0);
}
BTreeNode *pRoot = CreateNode(rootChar);
pRoot->pLeft = CreateTreeByPreOrderAndInOrder(
preOrder + 1, i,
inOrder, i);
pRoot->pRight = CreateTreeByPreOrderAndInOrder(
preOrder + 1 + i, preOrderSize - i - 1,
inOrder + 1 + i, inOrderSize - i - 1);
return pRoot;
}
void Test()
{
char *preOrder = "ABDCEF";
char *inOrder = "DBAECF";
BTreeNode *pRoot = CreateTreeByPreOrderAndInOrder(
preOrder, 6, inOrder, 6);
printf("Tree\n");
}