赞
踩
程序输入一个字符串(只包含小写字母),请按照字符的输入顺序建立平衡二叉排序树,并分别输出二叉树的先序序列、中序序列和后序序列,最后输出该二叉树向左旋转 90 度后的结构。
例如:向左旋转 90 度后,以每层向里缩进 4 个空格的方式输出,输出结果为
i
g
f
a
d
c
b
测试样例1
agxnzyimk
Preorder: xigamknzy
Inorder: agikmnxyz
Postorder: agknmiyzx
Tree:
z
y
x
n
m
k
i
g
a
测试样例2
asdfghjkl
Preorder: gdafjhlks
Inorder: adfghjkls
Postorder: afdhksljg
Tree:
s
l
k
j
h
g
f
d
a
#include<iostream>
using namespace std;
#define LH +1 //左高
#define EH 0 //等高
#define RH -1 //右高
typedef struct NODE
{
char data; //数据域
int bf; //平衡因子
NODE *Left; //左孩子
NODE *Right; //右孩子
} BSnode, *BSTree;
void R_Rotate(BSTree *ptr)
{//右旋
BSTree lc = (*ptr)->Left; //lc指向的*ptr的左孩子的根结点
(*ptr)->Left = lc->Right; //lc的右子树挂接为*ptr的左子树
lc->Right = *ptr;
*ptr = lc; //ptr指向新的结点
}
void L_Rotate(BSTree *ptr)
{//左旋
BSTree rc = (*ptr)->Right; //rc指向的*ptr的由孩子的根结点
(*ptr)->Right = rc->Left; //rc的左子树挂接为*ptr的右子树
rc->Left = *ptr;
*ptr = rc; //ptr指向新的结点
}
void LeftBalance(BSTree *root)
{//左平衡旋转处理
BSTree lc = (*root)->Left; //lc指向*root的左根结点
switch (lc->bf)
{//检测*root的左子树的平衡度,并作相应处理
case LH:
{//新结点插入在*root的左孩子的左子树上,要做单右旋处理
(*root)->bf = lc->bf = EH;
R_Rotate(root);
break;
}
case RH:
{//新结点插入在*root左孩子的右子树上要做双旋处理
BSTree rd = lc->Right;//rd指向*root的左孩子的右子树根上
switch (rd->bf)
{//修改*root及其左孩子的平衡因子
case LH:
{
(*root)->bf = RH;
lc->bf = EH;
break;
}
case EH:
{
(*root)->bf = lc->bf = EH;
break;
}
case RH:
{
(*root)->bf = EH;
lc->bf = LH;
break;
}
}
rd->bf = EH;
L_Rotate(&(*root)->Left);//对*root的左子树左左旋平衡处理
R_Rotate(root);//rd指向*t的左孩子的右子树根上
}
}
}
void RightBalance(BSTree *root)//右平衡旋转处理
{
BSTree lc;
BSTree rd;
lc = (*root)->Right;
switch (lc->bf)
{
case RH:
{
(*root)->bf = lc->bf = EH;
L_Rotate(root);
break;
}
case LH:
{
rd = lc->Left;
switch (rd->bf)
{
case LH:
{
(*root)->bf = EH;
lc->bf = RH;
break;
}
case EH:
{
(*root)->bf = lc->bf = EH;
break;
}
case RH:
{
(*root)->bf = LH;
lc->bf = EH;
break;
}
}
rd->bf = EH;
R_Rotate(&(*root)->Right);
L_Rotate(root);
}
}
}
//我们这里的平衡二叉树还要求是保持节点为中值,左子树数值大于根节点,且存在唯一性
int InsertAVL(BSTree *root, char e, bool *taller)
{
if ((*root) == NULL)
{//该树为一棵空树,创建一个新节点作为根节点
(*root) = new BSnode;
(*root)->bf = EH;//刚建立的树是平衡的
(*root)->data = e;
(*root)->Left = NULL;
(*root)->Right = NULL;
*taller = true;
}
else if (e == (*root)->data)
{//关键字相同,则不再继续插入
*taller = false;
return 0;
}
else if (e < (*root)->data)
{
if (!InsertAVL(&(*root)->Left, e, taller))//应该继续在*root的左子树进行搜索
{//未插入
return 0;
}
if (*taller)
{//已插入到*root的左子树中并且左子树长高,现在来检查*root的平衡度
switch ((*root)->bf)
{
case LH:
{//原本左子树比右子树高,平衡因子为-1
LeftBalance(root);//需要做左旋平衡处理
*taller = false;
break;
}
case EH:
{//原本左右树一样高,现在因为左子树长高树长高,平衡因子改为LH
(*root)->bf = LH;
*taller = true;//涨高了
break;
}
case RH:
{//原本右子树比左子树高,现在等高平衡因子为1
(*root)->bf = EH;
*taller = false;
break;
}
}
}
}
else
{
if (!InsertAVL(&(*root)->Right, e, taller))//应继续在*root的右子树中进行搜索
{//未插入
return 0;
}
if (*taller)
{//已插入到*root的右子树且右子树长高,现在来检查*root的平衡度
switch ((*root)->bf)
{
case LH:
{//原本左子树比右子树高,现在相等
(*root)->bf = EH;
*taller = false;
break;
}
case EH:
{//原来左右子树等高,现在因为右子树长高树长高
(*root)->bf = RH;
*taller = true;
break;
}
case RH:
{//原本右子树比左子树高,需要做右旋平衡处理
RightBalance(root);
*taller = false;
break;
}
}
}
}
return 1;
}
void printBIT(BSTree root, int x)
{
if (root != NULL)
{
printBIT(root->Right, x + 1);
for (int i = 0; i < x; i++)
cout << " ";
cout << root->data << endl;
printBIT(root->Left, x + 1);
}
}
void preorder(BSTree root)
{
if (root != NULL)
{
cout << root->data;
preorder(root->Left);
preorder(root->Right);
}
}
void inorder(BSTree root)//二叉树的中序遍历
{
if (root != NULL)
{
inorder(root->Left);
cout << root->data;
inorder(root->Right);
}
}
void postorder(BSTree root)
{
if (root != NULL)
{
postorder(root->Left);
postorder(root->Right);
cout << root->data;
}
}
int main()
{
//freopen("/Users/zhj/Downloads/test.txt", "r", stdin);
bool taller;//taller变量反应T长高与否
BSTree root = NULL;
string x;
cin >> x;
for (int i = 0; x[i]; i++)
{
InsertAVL(&root, x[i], &taller);
}
cout << "Preorder: ";//先序
preorder(root);
cout << endl << "Inorder: ";//中序
inorder(root);
cout << endl << "Postorder: ";//后序
postorder(root);
cout << endl << "Tree:" << endl;
printBIT(root, 0);
return 0;
}
平衡二叉树又称AVL树,它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。将二叉树上结点的平衡因子定义为该结点的左子树深度减去右子树的深度,平衡二叉树上所有结点的平衡因子只能是-1、0或1。
typedef struct NODE
{
char data; //数据域
int bf; //平衡因子
NODE *lchild; //左孩子
NODE *rchild; //右孩子
}BSnode, *BSTree;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。