一、概念
1、二叉树的递归定义
二叉树是有限的结点集合,这个集合:
- 或者是空;
- 或者由一个根结点和两棵互不相交的称为左子树和右子树的二叉树组成。
2、满二叉树
所有分支结点都有双分结点,并且叶结点都集中在二叉树的最下一层。
3、完全二叉树
最多只有下面两层的结点的度数小于2,且最下面一层的叶结点都依次排列在该层最左边的位置上。
二、二叉树的顺序存储结构
三、二叉树的链式存储结构
四、二叉树基本运算
1、定义二叉树结点
struct BTNode
{
QChar data;
BTNode * lchild{nullptr};
BTNode * rchild{nullptr};
};
2、创建二叉树
//创建二叉树
void CreateBTNode(BTNode * & root,QString binaryTreeBracketNotationString)
{
root = nullptr;
enum class processTreeType//当前字符处理的类型
{
leftChildTree,
rightChildTree,
noChildTree
};
processTreeType nowNodeProcessTreeType{processTreeType::noChildTree};
BTNode * currentNode{nullptr};//当前创建的结点
QStack<BTNode*> stack;
for(const auto & element : qAsConst(binaryTreeBracketNotationString))
{
if(element == '(')//表示一棵左子树的开始,即将前面刚创建的结点作为双亲结点进栈
{
stack.push(currentNode);
nowNodeProcessTreeType = processTreeType::leftChildTree;
}
else if(element == ')')//表示一棵子树的结束
{
stack.pop();
}
else if(element == ',')//表示一棵右子树的开始
{
nowNodeProcessTreeType = processTreeType::rightChildTree;
}
else//字母,说明应该创建一个结点
{
currentNode = new BTNode;
currentNode->data = element;
if(!root)
root = currentNode;
else
{
switch (nowNodeProcessTreeType)
{
case processTreeType::leftChildTree:stack.top()->lchild = currentNode;break;
case processTreeType::rightChildTree:stack.top()->rchild = currentNode;break;
case processTreeType::noChildTree:;break;
}
}
}
}
}
3、销毁二叉树
//递归销毁二叉树
void DestroyBT(BTNode * & node)
{
if (!node)
return;
else
{
DestroyBT(node->lchild);
DestroyBT(node->rchild);
delete node;
node = nullptr;
}
}
4、查找结点
//递归查找结点
const BTNode * findNode(const BTNode * node,const QChar & c)
{
if (!node)
return nullptr;
else if (node->data == c)
return node;
else
{
if (const BTNode * p = findNode(node->lchild,c))
return p;
else
return findNode(node->rchild,c);
}
}
5、求高度
//递归求高度
int BTNodeDepth(BTNode * node)
{
if (!node)
return 0; //空树的高度为0
else
{
int lchilddep = BTNodeDepth(node->lchild); //左子树的高度
int rchilddep = BTNodeDepth(node->rchild); //右子树的高度
return lchilddep > rchilddep ? lchilddep + 1 : rchilddep + 1;
}
}
6、输出二叉树的括号形式
//输出二叉树的括号形式
void DispBTNode(BTNode * node)
{
if (node)
{
std::cout<<node->data.toLatin1();
if (node->lchild || node->rchild)
{
std::cout<<"(";
DispBTNode(node->lchild); //递归处理左子树
if (node->rchild)
std::cout<<",";
DispBTNode(node->rchild); //递归处理右子树
std::cout<<")";
}
}
}
7、使用
QString binaryTreeBracketNotationString = "A(B(D(,G)),C(E,F))";
BTNode * root;
CreateBTNode(root,binaryTreeBracketNotationString);
qDebug()<<BTNodeDepth(root);
DispBTNode(root);
DestroyBT(root);
std::cout<<std::endl;