通常对于二叉树的创建采用两种方式:递归创建和非递归创建。本文在这里采用递归方法创建二叉树,并且叙述有关二叉树三种遍历方式以及求有关节点的相关问题等。
首先定义一个有关二叉树的结构体,结构体中包含整型的data,以及结构体类型的左右子树left和right。然后是创建有关二叉树的结点,相关代码如下:
typedef int DataType;
typedef struct BSTreeNode{
DataType data;
struct BSTreeNode *left;
struct BSTreeNode *right;
} BSTreeNode;
BSTreeNode *CreateNode(int data)
{
BSTreeNode *node = (BSTreeNode *)malloc(sizeof(BSTreeNode));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
对于创建二叉树,我采用了先序遍历的方法递归创建二叉树,下图是我的构思(用#号代表空结点):
下面代码中使用-1替换了上图中的#号来表示空结点,这里使用 preOrder来存储结点元素,然后定义了一个整形指针pUsedSize来标记在创建二叉树过程中已经使用过的元素个数,代码如下:
//创建出树的根节点
//创建过程中,使用的字符个数
BSTreeNode *CreateTree(int preOrder[], int size, int *pUsedSize)
{
if (size <= 0)
{
*pUsedSize = 0;
return NULL;
}
int leftUse, rightUse;
int rootValue = preOrder[0];
if (rootValue == -1)
{
*pUsedSize = 1;
return NULL;
}
BSTreeNode *root = CreateNode(rootValue);
root->left = CreateTree(preOrder + 1, size - 1, &leftUse);
root->right = CreateTree(preOrder + 1 + leftUse, size - 1 - leftUse, &rightUse);
//向老大报告实际使用情况
*pUsedSize = 1 + leftUse + rightUse;
return root;
}
完成创建二叉树的代码后,我又续写了相关代码来测试,测试代码如下:
void test()
{
int preOrder[] = { 1, 2, 4, -1,-1,-1,3 };
int size = sizeof(preOrder) / sizeof(int);
int usedSize;
BSTreeNode *root = CreateTree(preOrder, size, &usedSize);
}
int main()
{
test();
system("pause");
return 0;
}
测试结果如下:
接下来,我采用前序,中序,后序三种遍历方法遍历了我所创建的二叉树,相关代码如下:
//前序遍历
void Preorder(BSTreeNode *root)
{
// 终止条件
if (root == NULL) {
return;
}
// 根
printf("%d ", root->data);
// 左子树,子问题用递归处理
Preorder(root->left);
// 右子树,子问题用递归处理
Preorder(root->right);
}
//中序遍历
void InOrder(BSTreeNode *root)
{
if (root == NULL)
{
return;
}
InOrder(root->left);
printf("%d ", root->data);
InOrder(root->right);
}
//后序遍历
void PostOrder(BSTreeNode *root)
{
// 终止条件
if (root == NULL) {
return;
}
// 左子树,子问题用递归处理
PostOrder(root->left);
// 右子树,子问题用递归处理
PostOrder(root->right);
// 根
printf("%d ", root->data);
}
三种遍历结果如下:
完成二叉树的创建和遍历,然后来我会叙述一些有关二叉树的其它一些问题。通常我们会遇到求有关二叉树的节点个数,叶子结点个数,二叉树高度等相关问题。下面对于这些有关二叉树的问题我将一 一叙述:
1.求二叉树的节点个数问题,这里采用后序遍历二叉树,定义一个全局整形变量count来统计节点个数,代码如下:
//求树的结点的个数
int count = 0;
int GetSize1(BSTreeNode *root)
{
if (root == NULL) {
return 0;
}
GetSize1(root->left);
GetSize1(root->right);
count++;
return count;
}
2.求有关二叉树叶子节点个数的问题,代码如下:
//求叶子节点个数
int GeatLeafSize(BSTreeNode *root)
{
if (root == NULL)
{
return 0;
}
else{
if (root->left == NULL&&root->right == NULL)
{
return 1;
}
else
{
return GeatLeafSize(root->left) + GeatLeafSize(root->right);
}
}
}
3.求二叉树第k层节点个数的问题,代码如下:
//求第K层节点个数
int GetLevelkSize(BSTreeNode *root, int k)
{
assert(k >= 1);
if (root == NULL)
{
//空树,任意层都是0个
return 0;
}
if (k ==1)
{//第一层只有一个根节点
return 1;
}
int left = GetLevelkSize(root->left, k - 1);
int right = GetLevelkSize(root->right, k - 1);
return left + right;
}
4.求二叉树高度的问题,代码如下:
//求树的高度
#define MAX(a ,b) ((a)>(b)? (a):(b))
int GetHeight(BSTreeNode *root)
{
if (root == NULL)
{
return 0;
}
//当子树有一个节点的时候,可以写,也可以不写
//写的话,节省两次函数调用
return MAX(GetHeight(root->left), GetHeight(root->right)) + 1;
}
5.在二叉树中查找一个元素的问题,若找到返回其结点地址,否则返回NULL。代码如下:
//查找元素
BSTreeNode *Find(BSTreeNode *root, DataType data)
{
if (root == NULL)
{
return NULL;
}
if (root->data == data)
{
return root;
}
BSTreeNode *result = Find(root->left, data);
if (result != NULL)
{
return result;
}
result = Find(root->right, data);
if (result != NULL)
{
return result;
}
else
{
return NULL;
}
}