来源刘H同学
来源刘H同学
来源刘H同学
来源刘H同学
8 AVL树的判断
作者: 冯向阳时间限制: 1S章节: 课程设计
问题描述 :
目的:设计并实现一个算法Judge_AVL,用来判断1棵给定的二叉排序树是否是平衡二叉树。
提示:
(1)若一棵二叉排序树中每个结点的左、右子树的深度之差(平衡因子)的绝对值不超过1,则称这样的二叉树为平衡二叉树(AVL树)。
(2)在小组任务12的基础上,首先判断该二叉树是否是一棵二叉排序树。如不是,则可直接给出false(不是AVL树);如是,进入(3)
(3)使用任意的遍历方式对该二叉树进行遍历(测试数据使用非递归的后序遍历得到,参考个人任务12),在visit函数中计算访问的结点的平衡因子。参照个人任务13,但要稍作修改(不要通过数据元素的值,而是直接通过遍历到的结点地址来定位)。
(4)如有结点的平衡因子的绝对值超过1,则可给出false;如所有结点的平衡因子的绝对值都不超过1,则可给出true。
注意:结点的数据域的类型为string
参考函数原型:
(1)判断是否是AVL树
template<class ElemType>
bool Judge_AVL(BinaryTree<ElemType> &T);
(2)visit函数
template<class ElemType>
bool visit(BinaryTreeNode<ElemType> * root){
int lheight, rheight, flag;
if(!root) return false;
else{
cout<<root->data<<" ";
lheight = GetBinaryTreeHeight_Cursive(root->LChild);
rheight = GetBinaryTreeHeight_Cursive(root->RChild);
flag = lheight - rheight;
cout<<flag<<endl;
if( flag < -1 || flag > 1) return false;
}
return true;
}
输入说明 :
第一行:表示无孩子或指针为空的特殊分隔符
第二行:二叉树的先序序列(结点元素之间以空格分隔)
输出说明 :
如不是二叉排序树,直接输出false
否则,按照后序遍历
结点1的数据域的值 平衡因子(以空格分隔)
....
(如遇到结点的平衡因子不在范围内,在下一行显示false,终止)
(如所有结点的平衡因子都在范围内,在下一行显示true,终止)
-----------
#
06 04 02 01 # # 03 # # 05 # # 10 07 # 08 # 09 # # #
---------------
01 0
03 0
02 0
05 0
04 1
09 0
08 -1
07 -2
false
#include<iostream>
#include<algorithm>
#include<vector>
#include<sstream>
using namespace std;
bool flag = true;
bool flag2 = 1;
int k;
string c[1000];
vector<string>depart_string(string str)
{
vector<string>ans;
stringstream s(str);
string temp;
while (s >> temp)
{
ans.push_back(temp);
}
return ans;
}
template<class ElemType>
struct Node
{
public:
ElemType data;
Node<ElemType>* lchild;
Node<ElemType>* rchild;
};
template<class ElemType>
class BinaryTree
{
public:
Node<ElemType>* root;
void setroot(Node<ElemType>* head)
{
root = head;
}
Node<ElemType>* createbinarytree(vector<ElemType>ans, ElemType empty, int& n)
{
ElemType x = ans[n++];
if (x == empty)
{
return NULL;
}
else
{
Node<ElemType>* temp = new Node <ElemType>;
temp->data = x;
temp->lchild = createbinarytree(ans, empty, n);
temp->rchild = createbinarytree(ans, empty, n);
return temp;
}
}
bool postorderphyz(Node<ElemType>* root)
{
if (root == NULL)
return false;
Node<ElemType>* temp = root;
if (temp)
{
postorderphyz(temp->lchild);
postorderphyz(temp->rchild);
int phyz = GetBinaryTreeHeight_Cursive(temp->lchild) - GetBinaryTreeHeight_Cursive(temp->rchild);
if (flag)
cout << temp->data << " " << phyz << endl;
if (abs(phyz) > 1)
{
flag = false;
cout << "false" << endl;
exit(0);
}
}
return true;
}
void InOrderTraverse(Node<ElemType>* T)
{
if (T)
{
InOrderTraverse(T->lchild);
c[++k] = T->data;
if (k > 1 && c[k - 1] > T->data)
{
flag2 = 0;
return;
}
InOrderTraverse(T->rchild);
}
}
};
template<class ElemType>
int GetBinaryTreeHeight_Cursive(Node<ElemType>* root)
{
int ldepth, rdepth;
if (!root)
{
return 0;
}
else
{
ldepth = GetBinaryTreeHeight_Cursive(root->lchild);
rdepth = GetBinaryTreeHeight_Cursive(root->rchild);
return (ldepth > rdepth) ? (ldepth + 1) : (rdepth + 1);
}
}
template<class ElemType>
bool Judge_AVL(BinaryTree<ElemType> T)
{
Node<ElemType>* root = T.root;
int left = GetBinaryTreeHeight_Cursive(root->lchild);
int right = GetBinaryTreeHeight_Cursive(root->rchild);
if (abs(left - right) <= 1)
{
return true;
}
else
{
return false;
}
}
int main()
{
string empty;
string s;
getline(cin, empty);
getline(cin, s);
vector<string>ans = depart_string(s);
BinaryTree<string>bt;
int n = 0;
bt.setroot(bt.createbinarytree(ans, empty, n));
bt.InOrderTraverse(bt.root);
if (!flag2)
{
cout << "false";
return 0;
}
bool o = Judge_AVL(bt);
bt.postorderphyz(bt.root);
if (o && flag)
{
cout << "true";
}
return 0;
}