二叉树的重点不在于插入删除等等,比较重要的是遍历(包括深度遍历和层次遍历),其中层次遍历需要使用队列来实现,这里只是一些常用的操作,二叉树这个结构的算法实现使用递归较多。
1:定义
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
BTDataType data;
}BTNode;
此处使用链表的形式,用两个指针和一个数据域来实现
2:前序中序后序遍历
void PreOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
cout << root->data<<" ";
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
PreOrder(root->left);
cout << root->data << " ";
PreOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
PreOrder(root->left);
PreOrder(root->right);
cout << root->data << " ";
}
}
遍历通过递归的思想实现,当根节点为NULL,直接return。不为空时按照遍历的顺序进行(前序就是根->左->右,中序是左->根->右,后序是左->右->根)
其中根的遍历是直接输出其数据域来表示遍历过。
3:求节点个数
void TreeSize(BTNode* root, int* psize)
{
if (root == NULL)
return;
(*psize)++;
TreeSize(root->left,psize);
TreeSize(root->right, psize);
}
这里的是第一种求节点的方式,在外部定义一个int变量来计数。
int TreeSize2(BTNode* root)
{
return root == NULL ? 0 : TreeSize2(root->left) + TreeSize2(root->right) + 1;
}
这里是第二种求节点的方式,利用了分治的算法一棵树的节点也就是其左子树节点数和右子树节点数再加上本身根节点的数量。
4:求叶子节点
int TreeLeafSize(BTNode* root)
{
if (root == NULL)
return 0;
if (root->left == NULL && root->right == NULL)
return 1;
return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
如果等于空,则结束。如果左右节点都是空,则返回1(是叶子节点,需要计数)。然后进行递归即可。
5:求最大深度
int maxDepth(BTNode* root)
{
if (root == NULL)
return 0;
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
首先利用递归求出左右子树的深度,然后找其中最大的+1就是最大深度。(+1是因为需要算上根节点root)
6:复制一棵树
void Copy(BTNode*tree, BTNode*&NewTree)
{
if (tree == NULL)
{
NewTree = NULL;
return;
}
else
{
NewTree = new BTNode;
NewTree->data = tree->data;
Copy(tree->left, NewTree->left);
Copy(tree->right, NewTree->right);
}
}
这里类似于链表中的内容,可以使用二级指针,也可以使用引用来对本体进行修改操作,也是使用递归来实现。
7:删除一棵树
void DestoryTree(BTNode*&root)
{
if (root == NULL)
return;
DestoryTree(root->left);
DestoryTree(root->right);
free(root);
root = NULL;
}
删除不能从根开始删,需要从叶子开始删除。如果先删除了根,那么它的左右节点也将无法来找到。
最终全代码:
#include<iostream>
using namespace std;
typedef char BTDataType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
BTDataType data;
}BTNode;
void PreOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
cout << root->data<<" ";
PreOrder(root->left);
PreOrder(root->right);
}
}
void InOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
PreOrder(root->left);
cout << root->data << " ";
PreOrder(root->right);
}
}
void PostOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
PreOrder(root->left);
PreOrder(root->right);
cout << root->data << " ";
}
}
void TreeSize(BTNode* root, int* psize)
{
if (root == NULL)
return;
(*psize)++;
TreeSize(root->left,psize);
TreeSize(root->right, psize);
}
int TreeSize2(BTNode* root)
{
return root == NULL ? 0 : TreeSize2(root->left) + TreeSize2(root->right) + 1;
}
int TreeLeafSize(BTNode* root)
{
if (root == NULL)
return 0;
if (root->left == NULL && root->right == NULL)
return 1;
return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
int maxDepth(BTNode* root)
{
if (root == NULL)
return 0;
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
void Copy(BTNode*tree, BTNode*&NewTree)
{
if (tree == NULL)
{
NewTree = NULL;
return;
}
else
{
NewTree = new BTNode;
NewTree->data = tree->data;
Copy(tree->left, NewTree->left);
Copy(tree->right, NewTree->right);
}
}
void DestoryTree(BTNode*&root)
{
if (root == NULL)
return;
DestoryTree(root->left);
DestoryTree(root->right);
free(root);
root = NULL;
}
int main()
{
BTNode* A= (BTNode*)malloc(sizeof(BTNode));
A->data = 'A';
A->left = NULL;
A->right = NULL;
BTNode* B = (BTNode*)malloc(sizeof(BTNode));
B->data = 'B';
B->left = NULL;
B->right = NULL;
BTNode* C = (BTNode*)malloc(sizeof(BTNode));
C->data = 'C';
C->left = NULL;
C->right = NULL;
BTNode* D = (BTNode*)malloc(sizeof(BTNode));
D->data = 'D';
D->left = NULL;
D->right = NULL;
BTNode* E = (BTNode*)malloc(sizeof(BTNode));
E->data = 'E';
E->left = NULL;
E->right = NULL;
A->left = B;
A->right = C;
B->left = D;
B->right = E;
cout << "PreOrder Tree A:" << endl;
PreOrder(A);
cout << "\n";
cout << "THE SIZE OF TREE A:" << endl;
int Asize = 0;
TreeSize(A, &Asize);
cout<<Asize;
cout << "\n";
cout << "THE SIZE OF TREE A OF SIZE 2:" << endl;
cout<<TreeSize2(A);
cout << "\n";
cout << "THE LEAF OF TREE A:" << endl;
cout << TreeLeafSize(A);
cout << "\n";
cout << "THE COPY TREE :" << endl;
BTNode *tmp;
Copy(A, tmp);
PreOrder(tmp);
return 0;
}
最终的结果截图:
![](https://i-blog.csdnimg.cn/blog_migrate/770e531a82f1f8076676b0f1105328f9.png)