#include<iostream>
using namespace std; struct TreeNode
{
int height; //每一个结点都要保存自己的高度
int data;
TreeNode* leftC;
TreeNode* rightC;
}; //得到此时结点高度
int getHeight(TreeNode* s)
{
if (s != NULL)
{
return s->height;
}
return -1;
} //右旋
void rightRotate(TreeNode*& root)
{
TreeNode *l1 = root;
TreeNode *l2 = root->leftC;
l1->leftC = l2->rightC;
l2->rightC = l1;
l1->height = (getHeight(l1->leftC) > getHeight(l1->rightC) ? getHeight(l1->leftC) : getHeight(l1->rightC)) + 1;
l2->height = (getHeight(l2->leftC) > getHeight(l2->rightC) ? getHeight(l2->leftC) : getHeight(l2->rightC)) + 1;
root = l2;
} //左旋
void leftRotate(TreeNode*& root)
{
TreeNode *l1 = root;
TreeNode *l2 = root->rightC;
l1->rightC = l2->leftC;
l2->leftC = l1;
l1->height = (getHeight(l1->leftC) > getHeight(l1->rightC) ? getHeight(l1->leftC) : getHeight(l1->rightC)) + 1;
l2->height = (getHeight(l2->leftC) > getHeight(l2->rightC) ? getHeight(l2->leftC) : getHeight(l2->rightC)) + 1;
root = l2;
} //左右,先左旋,再右旋
void DoubleRotateLR(TreeNode* &n1)
{
leftRotate(n1->leftC);
rightRotate(n1);
} //右左,先右旋,后左旋
void DoubleRotateRL(TreeNode* &n1)
{
rightRotate(n1->rightC);
leftRotate(n1);
} void Insert(TreeNode** node, int data)
{
if (*node == NULL)
{
TreeNode* tmp = new TreeNode();
tmp->data = data;
tmp->height = 0;
tmp->leftC = NULL;
tmp->rightC = NULL;
*node = tmp;
return;
}
if ((*node)->data > data)//结点的值大于data
{
Insert(&((*node)->leftC), data);//不断插入 if ((getHeight((*node)->leftC) - getHeight((*node)->rightC)) == 2)
{//说明需要右旋
if (data < (*node)->leftC->data)
{
rightRotate(*node);
}
else
{
DoubleRotateLR(*node);
}
} }
else if ((*node)->data < data)//没有相同的值
{
Insert(&((*node)->rightC), data);
//如果高度之差为2的话就失去了平衡,需要旋转
if (2 == getHeight((*node)->rightC) - getHeight((*node)->leftC))
{
if (data > (*node)->rightC->data)
{
leftRotate(*node);
}
else
{
DoubleRotateRL(*node);
}
}
} (*node)->height = (getHeight((*node)->leftC) > getHeight((*node)->rightC) ? getHeight((*node)->leftC) : getHeight((*node)->rightC)) + 1;
} void preOrder(TreeNode* node)
{
if (node == NULL)
{
return;
}
cout << node->data << " ";
preOrder(node->leftC);
preOrder(node->rightC);
} void inOrderTraversal(TreeNode* root)
{
if(root)
{
inOrderTraversal(root->leftC);
cout << root->data << " ";
inOrderTraversal(root->rightC);
}
} int main()
{
int n;
cin>>n;
while(n-->0)
{
int num;
cin>>num; TreeNode *head=NULL; int point; for(int i=0;i<num;i++)
{
cin>>point;
Insert(&head, point);
} preOrder(head);
cout<<endl;
inOrderTraversal(head);
cout<<endl;
} return 0;
}

  

搭建AVL树的更多相关文章

  1. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  2. AVL树原理及实现(C语言实现以及Java语言实现)

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. AVL定义 AVL树是一种改进版的搜索二叉树.对于一般的搜索二叉树而言,如果数据恰好 ...

  3. AVL树

    AVL树 在二叉查找树(BST)中,频繁的插入操作可能会让树的性能发生退化,因此,需要加入一些平衡操作,使树的高度达到理想的O(logn),这就是AVL树出现的背景.注意,AVL树的起名来源于两个发明 ...

  4. AVL树的平衡算法(JAVA实现)

      1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...

  5. 【数据结构】平衡二叉树—AVL树

    (百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...

  6. 数据结构图文解析之:AVL树详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  7. 数据结构之平衡二叉树(AVL树)

    平衡二叉树(AVL树)定义如下:平衡二叉树或者是一棵空树,或者是具有以下性质的二叉排序树: (1)它的左子树和右子树的高度之差绝对值不超过1: (2)它的左子树和右子树都是平衡二叉树. AVL树避免了 ...

  8. PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由

    03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...

  9. 论AVL树与红黑树

    首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...

随机推荐

  1. Ubuntu 实现点击菜单栏图标最小化程序

    compizconfig-settings-manager http://blog.csdn.net/wdjhzw/article/details/39136057

  2. C# 语言规范_版本5.0 (第21章 附录C_参考资料)

    A. 参考资料 Unicode 联合会.The Unicode Standard, Version 3.0(Unicode 标准 3.0 版).Addison-Wesley,Reading,Massa ...

  3. for循环执行步骤

    for循环的具体步骤: for(var i=0;i<5;i++){ alert(1); } 第一步--->初始化i(初始化只在for循环中执行一次); 第二步--->执行条件i< ...

  4. .NET中的SqlBulkCopy类用法

    在开发过程中,经常会遇到向数据库插入大量数据的情况,那么如果是百万条数据,一条条的插入实在是太慢了,所以就有了SqlBulkCopy类. 本文中我将示范SqlBulkCopy类的不同应用. 以下面三张 ...

  5. JSON 和 JSONP 两兄弟

    项目中遇到这个新事物,转一篇不错的总结,原文 如今ajax威风凛凛 但说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决? 这两个问题目前都有不同 ...

  6. 默认conf指向位置

    查看nginx 默认配置文件所在位置 >> nginx -t  print --> nginx: the configuration file /etc/nginx/nginx.co ...

  7. linux安装GraphicsMagick

    下载GraphicsMagick-1.3.21.tar.gz 解压:tar -zxvf GraphicsMagick-1.3.21.tar.gz cd /usr/local/GraphicsMagic ...

  8. 清理SharePoint 2010的SQL Server 2008 R2日志数据库的方法!

    //来源:http://www.cnblogs.com/nbpowerboy/p/3380079.html 公司用SharePoint 2010已有三年多的时间了,上BPM项目也有2年多的时间,之前供 ...

  9. 6. Shell 流程控制

    1. 条件选择流程 1.1 if #!/bin/bash # if 格式 #if condition #then # command1 # command2 # ... # commandN #fi ...

  10. 针对ie9写特殊的样式

    <!--ie9样式重置--> <!--[if IE 9]> <style> select { background: none; padding-right: 0 ...