有关树的代码操作
二叉树的概念回顾
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8ba872c0e809000f08b970e9059a5073.png#pic_center)
二叉树的遍历
- 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。
- 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1dcb34ecddbd2d4f3774e9bb68e23598.png#pic_center)
三种遍历的代码操作
BinaryTree.c
#include"BinaryTree.h"
void PreOrder(BTNode* root)
{
if (root)
{
printf("%d", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root)
{
InOrder(root->left);
printf("%d", root->data);
InOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root)
{
PostOrder(root->left);
PostOrder(root->right);
printf("%d", root->data);
}
}
接下来用代码来验证一下遍历的结果
BinaryTree.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
typedef int BTNDataTye;
typedef struct BTNode
{
BTNDataTye data;
struct BTNode* left;
struct BTNode* right;
}BTNode;
void PreOrder(BTNode* root);
void InOrder(BTNode* root);
void PostOrder(BTNode* root);
BTNode* CreateNode(BTNDataTye data);
void TestBinTree();
BinaryTree.c
#include"BinaryTree.h"
void PreOrder(BTNode* root)
{
if (root)
{
printf("%d", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root)
{
InOrder(root->left);
printf("%d", root->data);
InOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root)
{
PostOrder(root->left);
PostOrder(root->right);
printf("%d", root->data);
}
}
BTNode* CreateNode(BTNDataTye data)
{
BTNode* pNewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->data = data;
pNewNode->left = NULL;
pNewNode->right = NULL;
return pNewNode;
}
BTNode* CreateBinaryTree()
{
BTNode* root = NULL;
BTNode* n1 = CreateNode(1);
BTNode* n2 = CreateNode(2);
BTNode* n3 = CreateNode(3);
BTNode* n4 = CreateNode(4);
BTNode* n5 = CreateNode(5);
BTNode* n6 = CreateNode(6);
root = n1;
root->left = n2;
n2->left = n3;
root->right = n4;
n4->left = n5;
n4->right = n6;
return root;
}
void TestBinTree()
{
BTNode* root = CreateBinaryTree();
printf("前序遍历结果为:\n");
PreOrder(root);
printf("\n");
printf("中序遍历结果为:\n");
InOrder(root);
printf("\n");
printf("后序遍历结果为:\n");
PostOrder(root);
printf("\n");
}
二叉树的层序遍历
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1c6ee130bf80f67e71d258c3fe6ba0ce.png#pic_center)
- 一开始我们传参数的时候,我们先把rooot放在1的位置,然后我们把root传入,那么我们这个时候就先打印root的值,当我们把root的值打印完成的时候,那么,我们就需要去打印root的左孩子的值和root的右孩子的值(那么,问题来了,在层序遍历里面,我们可不可以使用递归的方法进行遍历呢?----答案是不可以的,因为,如果继续使用递归的方式进行遍历的话,那么我们其实上使用的遍历方式,就和我们之前所使用的遍历方式是一样的了),那么我们要怎么去打印层序遍历的结果呢?—我们现在有两种处理的方式,在我们打印完1,2,4,三个结点之后,我们要去打印结点2的左孩子和结点2的右孩子,当然,结点4也是同样的处理方式;我们还有另外一种处理的方式,在我们打印结点2和结点4的时候,我们需要把结点2和结点4的左孩子和右孩子全部都保存起来,后续,既然我们已经把结点保存了,那么我们直接去遍历就可以了(现在,其实还是有问题的,我们现在应该采用什么样的结构来保存每一层中的结点呢?----得出的结论是我们需要用队列去保存每一层中的结点,因为先保存的结点需要先打印,类似于队列先进先出的特性,所以我们用队列来保存)
- 过程如下所示:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/851abf618640a20b5b787306da02857f.png#pic_center)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ba041ae815467a9318ed8e8de0210a4d.png#pic_center)
#include"BT.h"
void PreOrder(BTNode* root)
{
if (root)
{
printf("%d", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root)
{
InOrder(root->left);
printf("%d", root->data);
InOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root)
{
PostOrder(root->left);
PostOrder(root->right);
printf("%d", root->data);
}
}
BTNode* CreateNode(BTNDataTye data)
{
BTNode* pNewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->data = data;
pNewNode->left = NULL;
pNewNode->right = NULL;
return pNewNode;
}
BTNode* CreateBinaryTree()
{
BTNode* root = NULL;
BTNode* n1 = CreateNode(1);
BTNode* n2 = CreateNode(2);
BTNode* n3 = CreateNode(3);
BTNode* n4 = CreateNode(4);
BTNode* n5 = CreateNode(5);
BTNode* n6 = CreateNode(6);
root = n1;
root->left = n2;
n2->left = n3;
root->right = n4;
n4->left = n5;
n4->right = n6;
return root;
}
void TestBinTree()
{
BTNode* root = CreateBinaryTree();
printf("前序遍历结果为:\n");
PreOrder(root);
printf("\n");
printf("中序遍历结果为:\n");
InOrder(root);
printf("\n");
printf("后序遍历结果为:\n");
PostOrder(root);
printf("\n");
}
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
typedef int BTNDataTye;
typedef struct BTNode
{
BTNDataTye data;
struct BTNode* left;
struct BTNode* right;
}BTNode;
void PreOrder(BTNode* root);
void InOrder(BTNode* root);
void PostOrder(BTNode* root);
void LevelOrder(BTNode* root);
BTNode* CreateNode(BTNDataTye data);
void TestBinTree();
二叉树的销毁操作
- 我们在进行二叉树的销毁操作的时候,是要先去销毁根节点,还是要先去销毁根节点的左右子树,答案是我们需要先去销毁根节点的左右子树,然后再去销毁根节点,因为,如果我们先去销毁根节点的话,那么我们就找不到根节点的左右孩子了,所以,我们需要先去销毁根节点的左右子树,最后再去销毁根节点
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b19da58675bca0310d997c3e183b14cc.png)
- 那么,我们就可以很轻松的写出下面的代码,但是其实下面的代码是有问题的代码
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/32f2db763048770dee865b87ab2589ad.png)
- 上面的代码,问题所在,是因为,我们在代码的内部,修改了参数的值,而且,这个参数的值是我们需要代出去的值,所以我们传递一级指针是不可以了,因为如果使用一级指针的话,我们同时在代码的内部修改了变量的内容,那么这个变量的内容其实是不可以被代出代码块外部的,所以,我们在对树进行销毁的时候,我们必须要传递二级指针才可以,所以代码需要写成下面的样子
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3e4b9d62fd4c2101e10e5151514677ce.png)
- 最终的销毁结果如下所示:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5848f18e5f22ec0e9a09f93ae72007ea.png)
一些其他的操作:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b78012e51da30831bd26ab1424914575.png)
- 想要获取二叉树中结点的个数的话,那么我们直接求的话,其实是不好求的,但是我们只要知道了根节点左子树结点的个数,并且我们知道了根节点右子树的个数的话,那么我们只要将左子树结点的个数+右子树结点的个数,然后之后再+1就可以算出二叉树中结点的个数了
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6328256a7e9f12150ee9dbdd962174b8.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c7bb3d6faecdc9484a45d76db0a78776.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/bc0882d278df9b85bf384e9a20230f9a.png)
BinTree.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
typedef int BTNDataTye;
typedef struct BTNode
{
BTNDataTye data;
struct BTNode* left;
struct BTNode* right;
}BTNode;
void PreOrder(BTNode* root);
void InOrder(BTNode* root);
void PostOrder(BTNode* root);
int GetNodeCount(BTNode* root);
int GetLeafNodeCount(BTNode* root);
int GetKLevelNodeCount(BTNode* root);
BTNode* Find(BTNode* root, BTNDataTye data);
BTNode* CreateNode(BTNDataTye data);
void DestroyTree(BTNode** root);
void TestBinTree();
BinTree.c
#include"BinTree.h"
void PreOrder(BTNode* root)
{
if (root)
{
printf("%d", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root)
{
InOrder(root->left);
printf("%d", root->data);
InOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root)
{
PostOrder(root->left);
PostOrder(root->right);
printf("%d", root->data);
}
}
int GetNodeCount(BTNode* root)
{
if (root == NULL)
return 0;
else
return GetNodeCount(root->left) + GetNodeCount(root->right) + 1;
}
int GetLeafNodeCount(BTNode* root)
{
}
int GetKLevelNodeCount(BTNode* root);
BTNode* Find(BTNode* root, BTNDataTye data);
BTNode* CreateNode(BTNDataTye data)
{
BTNode* pNewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->data = data;
pNewNode->left = NULL;
pNewNode->right = NULL;
return pNewNode;
}
void DestroyTree(BTNode** root)
{
assert(root);
if (*root)
{
DestroyTree(&(*root)->left);
DestroyTree(&(*root)->right);
free(*root);
*root = NULL;
}
}
BTNode* CreateBinaryTree()
{
BTNode* root = NULL;
BTNode* n1 = CreateNode(1);
BTNode* n2 = CreateNode(2);
BTNode* n3 = CreateNode(3);
BTNode* n4 = CreateNode(4);
BTNode* n5 = CreateNode(5);
BTNode* n6 = CreateNode(6);
root = n1;
root->left = n2;
n2->left = n3;
root->right = n4;
n4->left = n5;
n4->right = n6;
return root;
}
void TestBinTree()
{
BTNode* root = CreateBinaryTree();
printf("前序遍历结果为:\n");
PreOrder(root);
printf("\n");
printf("中序遍历结果为:\n");
InOrder(root);
printf("\n");
printf("后序遍历结果为:\n");
PostOrder(root);
printf("\n");
printf("树中结点的个数为:%d\n", GetNodeCount(root));
DestroyTree(&root);
}
- 获取二叉树中叶子节点的个数
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6fcd2eb2c4e0b61e03e1e95959ba9c15.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0dde821477eb7764d5f6d2735c9f4735.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7e035fa868cdeae5b2bef2df91addf11.png)
- 获取二叉树中第k层结点的个数
- 那么现在有一个问题了,假设说,我这棵树,现在一共就只有3层的高度,我现在想要去求一下这棵树第10层一共有多少个结点,上面的代码还能正常运行吗?
- 经过验证之后,发现代码返回的结果是0,如果要求第10层的话,那么就是求3哪个结点的第8层,那很显而易见,第8层是没有结点的,所以肯定会返回0
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a6992fc224caa84c754d8367787281df.png)
- 在二叉树中查找某个节点
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d3ca09b44afe8348bf8ac252dafe838a.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c9f628f4241d0ee87d20185c721f26b5.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/473b38940b1f2794e0193ae74ae0f9b3.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/59b8cb92eacb9d25d1cf5ad62f467881.png)
- 获取二叉树的高度
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0461b85c3d060b4417ce244285fbc69f.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/36af46d7ea9b2e3e662ecc2795f2bd55.png)
- 判断一棵树是不是完全二叉树
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/eaab454a74bc951401160201df117059.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d68ad7656654d28ca5ffe250a5947af9.png)
BinaryTree.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
typedef int BTNDataTye;
typedef struct BTNode
{
BTNDataTye data;
struct BTNode* left;
struct BTNode* right;
}BTNode;
void PreOrder(BTNode* root);
void InOrder(BTNode* root);
void PostOrder(BTNode* root);
int GetNodeCount(BTNode* root);
int GetLeafNodeCount(BTNode* root);
int GetKLevelNodeCount(BTNode* root,unsigned int k);
int GetHeight(BTNode* root);
int BinaryTreeComplete(BTNode* root);
BTNode* Find(BTNode* root, BTNDataTye data);
BTNode* CreateNode(BTNDataTye data);
void DestroyTree(BTNode** root);
void TestBinTree();
BinaryTree.c
#include"BinTree.h"
void PreOrder(BTNode* root)
{
if (root)
{
printf("%d", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root)
{
InOrder(root->left);
printf("%d", root->data);
InOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root)
{
PostOrder(root->left);
PostOrder(root->right);
printf("%d", root->data);
}
}
int GetNodeCount(BTNode* root)
{
if (root == NULL)
return 0;
else
return GetNodeCount(root->left) + GetNodeCount(root->right) + 1;
}
int GetLeafNodeCount(BTNode* root)
{
if (root == NULL)
return 0;
if (root->left == NULL && root->right == NULL)
return 1;
return GetLeafNodeCount(root->left) + GetLeafNodeCount(root->right);
}
int GetKLevelNodeCount(BTNode* root, unsigned int k)
{
if (root == NULL || k == 0)
return 0;
if (k == 1)
return 1;
return GetKLevelNodeCount(root->left, k - 1) + GetKLevelNodeCount(root->right, k - 1);
}
BTNode* Find(BTNode* root, BTNDataTye data)
{
if (root == NULL)
return NULL;
if (root->data == data)
return root;
return Find(root->left, data) || Find(root->right, data);
}
int GetHeight(BTNode* root)
{
if (root == NULL)
return 0;
int leftheigth = 0;
int rightheight = 0;
leftheigth = GetHeight(root->left);
rightheight = GetHeight(root->right);
return leftheigth > rightheight ? leftheigth + 1 : rightheight + 1;
}
int BinaryTreeComplete(BTNode* root)
{
Queue q;
int flag = 0;
int ret = 0;
if (root == NULL)
return 1;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* cur = QueueFront(&q);
if (flag)
{
if (cur->left || cur->right)
break;
}
else
{
if (cur->left && cur->right)
{
QueuePush(&q, cur->left);
QueuePush(&q, cur->right);
}
else if (cur->left)
{
QueuePush(cur->left);
flag = 1;
}
else if (cur->right)
{
break;
}
else
{
flag = 1;
}
}
QueuePop(&q);
}
if (QueueEmpty(&q))
ret = 1;
QueueDestroy(&q);
return ret;
}
BTNode* CreateNode(BTNDataTye data)
{
BTNode* pNewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->data = data;
pNewNode->left = NULL;
pNewNode->right = NULL;
return pNewNode;
}
void DestroyTree(BTNode** root)
{
assert(root);
if (*root)
{
DestroyTree(&(*root)->left);
DestroyTree(&(*root)->right);
free(*root);
*root = NULL;
}
}
BTNode* CreateBinaryTree()
{
BTNode* root = NULL;
BTNode* n1 = CreateNode(1);
BTNode* n2 = CreateNode(2);
BTNode* n3 = CreateNode(3);
BTNode* n4 = CreateNode(4);
BTNode* n5 = CreateNode(5);
BTNode* n6 = CreateNode(6);
root = n1;
root->left = n2;
n2->left = n3;
root->right = n4;
n4->left = n5;
n4->right = n6;
return root;
}
void TestBinTree()
{
BTNode* root = CreateBinaryTree();
printf("前序遍历结果为:\n");
PreOrder(root);
printf("\n");
printf("中序遍历结果为:\n");
InOrder(root);
printf("\n");
printf("后序遍历结果为:\n");
PostOrder(root);
printf("\n");
printf("树中结点的个数为:%d\n", GetNodeCount(root));
printf("树中叶子结点的个数为:%d\n", GetLeafNodeCount(root));
printf("树中第k层结点的个数为:%d\n", GetKLevelNodeCount(root,3));
BTNode* cur = Find(root, 4);
if (cur != NULL)
{
printf("4 is in the tree\n");
}
else
{
printf("4 is not in the tree\n");
}
printf("树的高度为:%d\n", GetHeight(root));
DestroyTree(&root);
}
二叉树的拷贝
- 拷贝的操作其实和我们前面所给出二叉树的遍历操作是一个概念
- 根据二叉树的概念可以得知,空树也是属于二叉树的,如果二叉树非空的话,那么二叉树就是由根节点,根节点的左子树以及根节点的右子树组成,那么我们在进行二叉树的拷贝的时候,就去先拷贝二叉树的根节点
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/107ae484408e7732518510719bac7928.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9c3f47a7cc5d68a44ba43985f130c65f.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6e3340de1d1e1b1d3ff01d71ee37f2f8.png)
二叉树的创建
- 因为之前虽然说我们把树给出来了,但是当时所给出的二叉树的创建方式并不是真正的二叉树的创建方式,现在需要给出真正的二叉树的创建方式(当时只是给出了一种简单的方式把那颗二叉树模拟出来了)
- 一开始创建的时候我需要先去创建根节点,我们要先把根节点创建出来,然后去创建根节点的左子树和根节点的右子树
- 按照上面的思路,可以写出像下面这样的代码
BTNode* CreateBinTree(int array[], int size,int index)
{
BTNode* root = NULL;
if (index < size)
{
root = CreateNode(array[index]);
root->left = CreateBinTree(array, size, ++index);
root->right = CreateBinTree(array, size, ++index);
}
return root;
}
- 那我们现在写好了代码之后,就需要对我们所写好的代码来进行验证,那么我现在需要创建一棵二叉树,我就需要把二叉树中的结点全部保存在数组中,那么,现在问题又来了,我们数组中元素的序列应该如何给出呢?
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6706bf2c964dbdb1fe77a7273d5ec113.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/07ed451b66a2a8a27126c03916295fdf.png)
- 但是像上面那样写的话,其实是有问题的,因为上面的代码会给我们创建出来一棵单支树,因为从该序列中无法确定某个结点的子树是否存在,所以我们需要对之前所给出的序列来进行一系列的调整,如果某个结点是没有左右子树的,那么我们需要对其来进行标记,从而表明这个结点时没有左右子树的
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/66c812b17355668b48c7b357814c4719.png)
- #表示这个结点并不存在,如果遇到#就表示这个结点是没有的。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9d17a610f4b2146a8402d3d3e71ba7aa.png)
- 所以我们需要对上面所写出的代码进行一些调整
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/fa3bf1efd91121466236fbe8a461daae.png)
- 但是按照上图这样改完代码之后,其实这个代码还是有问题的,问题出现在index参数上,原因如下图所示
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0ee05de90bec1d43c9146f604a140606.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3cc3f3a083fcc0a9e97c6f45ebebbc1c.png)
BTNode* CreateBinaryTree(int array[], int size, int *index,int invalid)
{
BTNode* root = NULL;
if (*index < size && invalid != array[*index])
{
root = CreateNode(array[*index]);
++(*index);
root->left = CreateBinaryTree(array, size, index,invalid);
++(*index);
root->right = CreateBinaryTree(array, size, index,invalid);
}
return root;
}
BinTree.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
typedef int BTNDataTye;
typedef struct BTNode
{
BTNDataTye data;
struct BTNode* left;
struct BTNode* right;
}BTNode;
void PreOrder(BTNode* root);
void InOrder(BTNode* root);
void PostOrder(BTNode* root);
int GetNodeCount(BTNode* root);
int GetLeafNodeCount(BTNode* root);
int GetKLevelNodeCount(BTNode* root, unsigned int k);
int GetHeight(BTNode* root);
int BinaryTreeComplete(BTNode* root);
BTNode* Find(BTNode* root, BTNDataTye data);
BTNode* CreateNode(BTNDataTye data);
void DestroyTree(BTNode** root);
BTNode *CopyBinTree(BTNode* root);
BTNode* CreateBinaryTree(int array[], int size, int* index, int invalid);
void TestBinTree();
BinTree.c
#include"Tree.h"
void PreOrder(BTNode* root)
{
if (root)
{
printf("%d ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root)
{
InOrder(root->left);
printf("%d ", root->data);
InOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root)
{
PostOrder(root->left);
PostOrder(root->right);
printf("%d ", root->data);
}
}
int GetNodeCount(BTNode* root)
{
if (root == NULL)
return 0;
else
return GetNodeCount(root->left) + GetNodeCount(root->right) + 1;
}
int GetLeafNodeCount(BTNode* root)
{
if (root == NULL)
return 0;
if (root->left == NULL && root->right == NULL)
return 1;
return GetLeafNodeCount(root->left) + GetLeafNodeCount(root->right);
}
int GetKLevelNodeCount(BTNode* root, unsigned int k)
{
if (root == NULL || k == 0)
return 0;
if (k == 1)
return 1;
return GetKLevelNodeCount(root->left, k - 1) + GetKLevelNodeCount(root->right, k - 1);
}
BTNode* Find(BTNode* root, BTNDataTye data)
{
BTNode* ret = NULL;
if (root == NULL)
return NULL;
if (root->data == data)
return root;
(ret = Find(root->left, data)) || (ret = Find(root->right, data));
return ret;
}
int GetHeight(BTNode* root)
{
if (root == NULL)
return 0;
int leftheigth = 0;
int rightheight = 0;
leftheigth = GetHeight(root->left);
rightheight = GetHeight(root->right);
return leftheigth > rightheight ? leftheigth + 1 : rightheight + 1;
}
BTNode* CreateNode(BTNDataTye data)
{
BTNode* pNewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->data = data;
pNewNode->left = NULL;
pNewNode->right = NULL;
return pNewNode;
}
void DestroyTree(BTNode** root)
{
assert(root);
if (*root)
{
DestroyTree(&(*root)->left);
DestroyTree(&(*root)->right);
free(*root);
*root = NULL;
}
}
BTNode *CopyBinTree(BTNode* root)
{
BTNode* NewRoot = NULL;
if (root)
{
NewRoot = CreateNode(root->data);
NewRoot->left = CopyBinTree(root->left);
NewRoot->right = CopyBinTree(root->right);
}
return NewRoot;
}
BTNode* CreateBinaryTree(int array[], int size, int *index,int invalid)
{
BTNode* root = NULL;
if (*index < size && invalid != array[*index])
{
root = CreateNode(array[*index]);
++(*index);
root->left = CreateBinaryTree(array, size, index,invalid);
++(*index);
root->right = CreateBinaryTree(array, size, index,invalid);
}
return root;
}
void TestBinTree()
{
int array[] = { 1,2,3,-1,-1,-1,4,5,-1,-1,6 };
int index = 0;
BTNode* root = CreateBinaryTree(array,sizeof(array)/sizeof(array[0]),&index,-1);
BTNode* NewRoot = NULL;
printf("前序遍历结果为:\n");
PreOrder(root);
printf("\n");
printf("中序遍历结果为:\n");
InOrder(root);
printf("\n");
printf("后序遍历结果为:\n");
PostOrder(root);
printf("\n");
printf("树中结点的个数为:%d\n", GetNodeCount(root));
printf("树中叶子结点的个数为:%d\n", GetLeafNodeCount(root));
printf("树中第k层结点的个数为:%d\n", GetKLevelNodeCount(root, 3));
BTNode* cur = Find(root, 4);
if (cur != NULL)
{
printf("4 is in the tree\n");
}
else
{
printf("4 is not in the tree\n");
}
printf("树的高度为:%d\n", GetHeight(root));
NewRoot = CopyBinTree(root);
printf("前序遍历结果为:\n");
PreOrder(root);
printf("\n");
printf("中序遍历结果为:\n");
InOrder(root);
printf("\n");
printf("后序遍历结果为:\n");
PostOrder(root);
printf("\n");
DestroyTree(&root);
DestroyTree(&NewRoot);
}