一、二叉树结构定义
节点定义:
typedef char ElemType;
typedef struct tagBitNode
{
char data;
struct tagBitNode *left;
struct tagBitNode *right;
} BitNode;
二、构建二叉树
手动构建一个如图所示的二叉树。
新节点生成函数:
// 生成新节点
BitNode *newBitNode(ElemType data)
{
BitNode *root = (BitNode *)malloc(sizeof(BitNode));
if(!root)
{
return NULL;//failed
}
root->data = data;
root->left = NULL;
root->right = NULL;
return root;
}//end of function newBitNode
三、深度遍历
3.1 先序遍历
二叉树先序遍历的过程:
(1)访问根节点
(2)先序遍历左子树
(3)先序遍历右子树
递归算法:
//基于先序遍历的递归算法: 根左右
void preOrderTraverse(BitNode *root)
{
if(root)
{
printf("%c ", root->data);
preOrderTraverse(root->left);
preOrderTraverse(root->right);
}
}// end of function preOrderTraverse
先序遍历结果:
A B D G C E F
3.2 中序遍历
中序遍历的过程:
(1)中序遍历左子树
(2)访问根节点
(3)中序遍历右子树
递归算法:
// 中序遍历: 左根右
void inOrderTraverse(BitNode *root)
{
if(root)
{
inOrderTraverse(root->left);
printf("%c ", root->data);
inOrderTraverse(root->right);
}
}// end of function inOrderTraverse
中序遍历结果:
D G B A E C F
3.3 后序遍历
后序遍历的过程;
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根节点
递归算法:
// 后序遍历: 左右根
void postOrderTraverse(BitNode *root)
{
if(root)
{
postOrderTraverse(root->left);
postOrderTraverse(root->right);
printf("%c ", root->data);
}
}//end of function postOrderTraverse
后序遍历结果:
G D B E F C A
四、计算二叉树的高度
递归算法:
// 计算二叉树高,基于后序遍历
int bitTreeDepth(BitNode *root)
{
if(!root) return 0;//基线条件,空树高度为0
int leftDepth = bitTreeDepth(root->left);
int rightDepth = bitTreeDepth(root->right);
return leftDepth > rightDepth ? ++leftDepth : ++rightDepth;
}
计算结果:
Depth: 4
五、层次遍历
层次遍历需要借助队列来实现。
(1)树非空,则根节点入队
(2)访问队首节点,然后将其出队。若有左孩子,将其左孩子入队;若有右孩子,将其右孩子入队
(3)重复(2)过程至队列空。
(偷个懒,直接使用C++的STL库中queue)
// 层序遍历,借助队列来实现
void levelOrderTraverse(BitNode *root)
{
if(!root) return; //空树,则结束
std::queue<BitNode*> q;
q.push(root);
while(!q.empty())
{
BitNode *temp = q.front();
printf("%c ", temp->data);
q.pop();
if(temp->left) q.push(temp->left);
if(temp->right) q.push(temp->right);
}
}
层序遍历结果:
A B C D E F G
六、查找和修改节点的值
基于先序遍历整棵树,将符合查询条件的节点都进行修改。使用时需确保待修改的值存在。如果查找的值不存在,无任何返回值。
// 将指定值修改为给定值,前提是指定值必须存在且唯一
// 基于先序遍历
void change(BitNode *root, ElemType data, ElemType newData)
{
if(root)
{
if(root->data == data)
{
root->data = newData;
}
change(root->left, data, newData);
change(root->right, data, newData);
}
}
七、销毁二叉树
只能用后序遍历的顺序销毁二叉树。
// 销毁二叉树,必须用后序方式
// 先释放孩子节点,再释放根节点
void destroyBitTree(BitNode *root)
{
if(root)
{
destroyBitTree(root->left);
destroyBitTree(root->right);
free(root);
}
}//end of function destroyBitTree
八、测试代码
void test()
{
BitNode *root = newBitNode('A');
BitNode *nodeB = newBitNode('B');
BitNode *nodeC = newBitNode('C');
BitNode *nodeD = newBitNode('D');
BitNode *nodeE = newBitNode('E');
BitNode *nodeF = newBitNode('F');
BitNode *nodeG = newBitNode('G');
root->left = nodeB;
root->right = nodeC;
nodeB->left = nodeD;
nodeD->right = nodeG;
nodeC->left = nodeE;
nodeC->right = nodeF;
preOrderTraverse(root);
printf("\n");
inOrderTraverse(root);
printf("\n");
postOrderTraverse(root);
printf("\n");
printf("Depth: %d", bitTreeDepth(root));
printf("\n");
levelOrderTraverse(root);
printf("\n");
destroyBitTree(root);
}