输出展示:

相关文章目录
MFC二叉树可视化绘制 (C++)—— 插入、删除、先序遍历、中序遍历、后序遍历、层序遍历(基于平衡二叉树实现)
文章目录
前言
该程序由c语言编写,可运行于vs环境下,可轻易转换成C++代码。
一、实现功能
实现操作:结点的插入、删除。
实现输出:输出先序遍历、中序遍历、后序遍历、层序遍历的结果。
二、代码设计
1. 定义平衡二叉树的结点结构
平衡二叉树的结点结构:
// 平衡二叉树的结点结构
typedef struct BiTNode
{
int data;
int bf; // 平衡因子
BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
BiTree 为指向树结点的指针,用于表示树对象。
2. 定义层序遍历链队列相关结构和函数
链队列结构:
/* 链队列结点结构(用于层序遍历) */
typedef struct QNode {
BiTree t; // 结点数据域
struct QNode* next; // 结点指针域
}QNode, * QueuePtr;
/* 链队列结构(用于层序遍历) */
typedef struct {
QueuePtr front; // 队首指针
QueuePtr rear; // 队尾指针
}LinkQueue;
初始化链队列函数、进队函数、出队函数定义:
/* 初始化链队列函数 */
Status InitQueue(LinkQueue& Q)
{
// 创建一个带附加头结点的空链队列
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q.front) {
return ERROR;
}
Q.front->next = NULL;
return OK;
}
/* 进队函数 */
/* e:插入元素 */
Status EnQueue(LinkQueue& Q, BiTree e)
{
// 将元素e插入到链队列中
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if (!p) {
return ERROR;
}
p->t = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
/* 出队函数 */
/* e:出队元素 */
Status DeQueue(LinkQueue& Q, BiTree& e)
{
// 出队,将出队元素放入e中
QueuePtr p;
if (Q.rear == Q.front) {
return ERROR;
}
p = Q.front->next;
e = p->t;
Q.front->next = p->next;
if (Q.rear == p) {
Q.rear = Q.front;
}
free(p);
return OK;
}
3. 定义结点旋转函数 —— 用于二叉树的结点平衡
LL调整(左单旋)、RR调整(右单旋)、LR调整(先左旋再右旋)、RL调整(先右旋再左旋)。
关于平衡二叉树的旋转问题请参考:平衡二叉树的构造过程图解
// 右旋处理,即LL调整
void R_Rotate(BiTree* p)
{
BiTree L;
L = (*p)->lchild;
(*p)->lchild = L->rchild;
L->rchild = *p;
*p = L;
}
// 左旋处理,即RR调整
void L_Rotate(BiTree* p)
{
BiTree R;
R = (*p)->rchild;
(*p)->rchild = R->lchild;
R->lchild = *p;
*p = R;
}
// 左平衡旋转处理,包括 LL 和 LR 调整
void LeftBalance(BiTree* T)
{
BiTree L, Lr;
L = (*T)->lchild;
switch (L->bf)
{
case 1: // 新结点插入在T的左孩子的左子树上,为LL型,作右旋处理即LL调整
(*T)->bf = L->bf = 0;
R_Rotate(T);
break;
case -1: // 新结点插入在T的左孩子的右子树上,为LR型,作双旋处理
Lr = L->rchild;
switch (Lr->bf)
{
case 1:
(*T)->bf = -1;
L->bf = 0;
break;
case 0:
(*T)->bf = L->bf = 0;
break;
case -1:
(*T)->bf = 0;
L->bf = 1;
break;
}
Lr->bf = 0;
L_Rotate(&(*T)->lchild); // 先对T的左子树进行左旋处理即RR调整
R_Rotate(T); // 再对T进行右旋处理即LL调整
}
}
// 右平衡旋转处理,包括 RR 和 RL 调整
void RightBalance(BiTree* T)
{
BiTree R, Rl;
R = (*T)->rchild;
switch (R->bf)
{
case -1: // 新结点插入在T的右孩子的右子树上,为RR型,作左旋处理即RR调整
(*T)->bf = R->bf = 0;
L_Rotate(T);
break;
case 1: // 新结点插入在T的右孩子的左子树上,为RL型,作双旋处理
Rl = R->lchild;
switch (Rl->bf)
{
case 1:
(*T)->bf = 0;
R->bf = -1;
break;
case 0:
(*T)->bf = R->bf = 0;
break;
case -1:
(*T)->bf = 1;
R->bf = 0;
break;
}
Rl->bf = 0;
R_Rotate(&(*T)->rchild); // 先对T的左子树进行左旋即RR调整
L_Rotate(T); // 再对T进行右旋即LL调整
}
}
4. 定义结点插入函数
// 若在平衡二叉树T中不存在和 e 具有相同数据的结点,则插入数据元素为 e 的新结点,
// 若因插入使二叉排序树失去平衡,则要作平衡调整,
// 布尔变量taller表示 T 的深度是否增加,TRUE表示增加,FALSE表示没有增加
Status InsertAVL(BiTree* T, int e, Status* taller)
{
if (!*T)
{
*T = (BiTree)malloc(sizeof(BiTNode));
if (!*T) {
return ERROR;
}
else {
(*T)->data = e;
(*T)->lchild = (*T)->rchild = NULL;
(*T)->bf =

本文介绍了使用C++编程实现AVL树的详细步骤,包括节点插入、删除操作以及先序、中序、后序和层序遍历。代码实现了平衡二叉树的节点平衡调整,如左旋、右旋以及双旋操作,确保树的平衡。此外,还提供了完整的主函数测试案例,展示了各种操作后的结果。
最低0.47元/天 解锁文章
1194

被折叠的 条评论
为什么被折叠?



