搭建AVL树

#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;
}

  

时间: 2024-08-26 00:21:49

搭建AVL树的相关文章

AVL树

定义:AVL树是每个节点左子树和右子树的高度差最大为1的二叉查找树 不平衡节点:假设在懒惰删除(删除操作时,并不删除节点,只是对节点进行特定标记)的条件下,插入操作有可能破坏AVL树的平衡特性. 如果插入节点导致平衡性被破坏,那么平衡性遭到破坏的节点只可能出现在插入节点到根节点的路径上.因为插入操作只会改变 插入节点的父节点的高度,而这些父节点就再这条路径上. 调整:对于平衡性遭到破坏的节点,需要对其进行调整以恢复平衡性.调整的方法称为旋转,针对不同的插入情况,调整操作稍有不同. 下面先对插入情

数据结构--AVL树

AVL树是高度平衡的二叉搜索树,较搜索树而言降低了树的高度:时间复杂度减少了使其搜索起来更方便: 1.性质: (1)左子树和右子树高度之差绝对值不超过1: (2)树中每个左子树和右子树都必须为AVL树: (3)每一个节点都有一个平衡因子(-1,0,1:右子树-左子树) (4)遍历一个二叉搜索树可以得到一个递增的有序序列 2.结构: 平衡二叉树是对二叉搜索树(又称为二叉排序树)的一种改进.二叉搜索树有一个缺点就是,树的结构是无法预料的.任意性非常大.它仅仅与节点的值和插入的顺序有关系.往往得到的是

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

欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. AVL定义 AVL树是一种改进版的搜索二叉树.对于一般的搜索二叉树而言,如果数据恰好是按照从小到大的顺序或者从大到小的顺序插入的,那么搜索二叉树就对退化成链表,这个时候查找,插入和删除的时间都会上升到O(n),而这对于海量数据而言,是我们无法忍受的.即使是一颗由完全随机的数据构造成的搜索二叉树,从统计角度去分析,在进行若甘次的插入和删除操作,这个搜索二叉树的高度也不能令人满意.这个

数据结构与算法系列----平衡二叉树(AVL树)

一:背景 平衡二叉树(又称AVL树)是二叉查找树的一个进化体,由于二叉查找树不是严格的O(logN),所以引入一个具有平衡概念的二叉树,它的查找速度是O(logN).所以在学习平衡二叉树之前,读者需要了解二叉查找树的实现,具体链接:二叉查找树 那么平衡是什么意思?我们要求对于一棵二叉查找树 ,它的每一个节点的左右子树高度之差不超过1.(对于树的高度的约定:空节点高度是0:叶子节点高度是1.)例如下图: 如果我们的二叉查找树是不平衡该怎么办?进行旋转.经过分析发现,出现不平衡无外乎四种情况,下面我

AVL树 冲突链表

;红黑树只不过是AVL树的变种而已 ,平衡方式耕地,意味着比AVL旋转的次数少,长应用于关联数组 红黑树和AVL树在实际开发中比较常用 ;AVL树二叉平衡树 适合在内存中使用速度会达到最优化,要是在文件中那么速度大大降低 ;文件中适合用b+树,B+树读文件一次读的孩子结点比较多,一次read读取尽量多的结点到内存中缓存起来,下次直接从内存中返回. ;百万级别的数据存文件用c库函数利用缓冲区一次不要读两个缓冲区的内容(<4096)设计树的结构,超过就自己设计fopen喽自己做大的缓冲区,降低文件访

AVL树,红黑树,B-B+树,Trie树原理和应用

前言:本文章来源于我在知乎上回答的一个问题 AVL树,红黑树,B树,B+树,Trie树都分别应用在哪些现实场景中? 看完后您可能会了解到这些数据结构大致的原理及为什么用在这些场景,文章并不涉及具体操作(如插入删除等等) 目录 AVL树 AVL树原理与应用 红黑树 红黑树原理与应用 B/B+树 B/B+树原理与应用 Trie树 Trie树原理与应用 AVL树 简介: AVL树是最早的自平衡二叉树,在早期应用还相对来说比较广,后期由于旋转次数过多而被红黑树等结构取代(二者都是用来搜索的),AVL树内

AVL树的初步生成与插入操作

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.构造与调整方法 平衡二叉树的常用算法有红黑树.AVL.Treap等. 最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量. AVL是最先发明的

图解平衡二叉树,AVL树(一)

图解平衡二叉树,AVL树(一) 学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建立的树如图2,才能够最大地体现二叉树的优点. 在上述的例子中,图2就是一棵平衡二叉树.科学家们提出平衡二叉树,就是为了让树的查找性能得到最大的体现(至少我是这样理解的,欢迎批评改正).下面进入今天的正题,平衡二叉树. AVL的定义 平衡二叉查找树:简称平衡二叉树.由前

平衡二叉搜索树(AVL树)的原理及实现源代码(有图文详解和C++、Java实现代码)

一.AVL树(平衡二叉搜索树)是什么? AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的.AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个非叶子结点的左右子树的高度之差的绝对值(平衡因子)最多为1. 例如: 5             5 / \            /  \ 2   6         2   6 / \    \         / \ 1  4   7       1  4