**
二叉树的基本操作
**
1.二叉树的基本概念
在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。
一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为log2n+1。深度为k的完全二叉树,至少有2^(k-1)个节点,至多有2^k-1个节点。
2. 声明以及头文件
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
typedef char BDataType;
typedef struct BinTreeNode {
struct BinTreeNode* _pLeft;
struct BinTreeNode* _pRight;
BDataType _data;
}BinTreeNode,*PBinTreeNode;
void CreateBinTree(PBinTreeNode* pRoot, const BDataType *a, int size, BDataType invalid);
void PreOrder(PBinTreeNode pRoot);
void InOrder(PBinTreeNode pRoot);
void BackOrder(PBinTreeNode pRoot);
PBinTreeNode CopyBinTree(PBinTreeNode pRoot);
void DestoryBinTree(PBinTreeNode *pRoot);
void TestBinTree();
void TestBinTree1();
void TestBinTree2();
3.相关的操作函数:
1>二叉树的创建:
PBinTreeNode BuyTreeNode(BDataType x)//创建树节点
{
PBinTreeNode pNewRoot = (PBinTreeNode)malloc(sizeof(BinTreeNode));
assert(pNewRoot);
pNewRoot->_pLeft = NULL;
pNewRoot->_pRight = NULL;
pNewRoot->_data = x;
return pNewRoot;
}
void _CreateBinTree(PBinTreeNode* pRoot,const BDataType *a, int size, int *index, BDataType invalid)//辅助函数
{
if (size>(*index) && a[*index] != invalid)//判断序列值是否非法并判断size与index大小
{
*pRoot = BuyTreeNode(a[*index]);
++(*index);
_CreateBinTree(&(*pRoot)->_pLeft, a, size, index, invalid);
++(*index);
_CreateBinTree(&(*pRoot)->_pRight, a, size, index, invalid);
}
}
void CreateBinTree(PBinTreeNode* pRoot,const BDataType *a, int size, BDataType invalid)//创建一颗二叉树
{
int index = 0;
_CreateBinTree(&(*pRoot), a, size, &index, invalid);
}
2>.二叉树的遍历:
void PreOrder(PBinTreeNode pRoot)//递归实现前序遍历
{
if (NULL == pRoot)
return;
printf("%c ", pRoot->_data);
PreOrder(pRoot->_pLeft);
PreOrder(pRoot->_pRight);
}
void InOrder(PBinTreeNode pRoot)//递归实现中序遍历
{
if (NULL == pRoot)
return;
InOrder(pRoot->_pLeft);
printf("%c ", pRoot->_data);
InOrder(pRoot->_pRight);
}
void BackOrder(PBinTreeNode pRoot)//递归实现后序遍历
{
if (NULL == pRoot)
return;
BackOrder(pRoot->_pLeft);
BackOrder(pRoot->_pRight);
printf("%c ", pRoot->_data);
}
3>二叉树的拷贝
PBinTreeNode CopyBinTree(PBinTreeNode pRoot)//二叉树的拷贝
{
PBinTreeNode pNewRoot = NULL;
if (pRoot)
{
pNewRoot = BuyTreeNode(pRoot->_data);
//拷贝根节点左子树
pNewRoot->_pLeft = CopyBinTree(pRoot->_pLeft);
//拷贝根节点右子树
pNewRoot->_pRight = CopyBinTree(pRoot->_pRight);
}
return pNewRoot;
}
4>二叉树的销毁
void DestoryBinTree(PBinTreeNode *pRoot)//销毁二叉树
{
assert(pRoot);
if (*pRoot)
{
DestoryBinTree(&(*pRoot)->_pLeft);
DestoryBinTree(&(*pRoot)->_pRight);
free(*pRoot);
}
}
5>一些测试函数:
void TestBinTree()//二叉树的创建和遍历
{
const char* str = "ABD###CE##F";
PBinTreeNode Root = NULL;
CreateBinTree(&Root, str, strlen(str), '#');
printf("PreOrder:");
PreOrder(Root);
printf("\n");
printf("InOrder:");
InOrder(Root);
printf("\n");
printf("BackOrder:");
BackOrder(Root);
printf("\n");
}
void TestBinTree1()//二叉树的拷贝
{
const char* str = "ABD###CE##F";
PBinTreeNode Root = NULL;
CreateBinTree(&Root, str, strlen(str), '#');
printf("PreOrder:");
PreOrder(Root);
printf("\n");
PBinTreeNode pNewRoot = CopyBinTree(Root);
printf("PreOrder:");
PreOrder(pNewRoot);
printf("\n");
}
void TestBinTree2()//二叉树的销毁
{
const char* str = "ABD###CE##F";
PBinTreeNode Root = NULL;
CreateBinTree(&Root, str, strlen(str), '#');
printf("PreOrder:");
PreOrder(Root);
printf("\n");
DestoryBinTree(&Root);
}
4.程序运行的结果
- 遍历结果
- 拷贝结果
- 销毁结果
5.小结
二叉树在计算机编程中应用非常广泛,因此我们要认真学习,后期也会分享一些非递归实现二叉树的方法。
以上就是我对于二叉树递归实现的一些方法,希望可以与广大编程爱好者,一起学习,一起进步。