AVL添加

平衡二叉树,是一种二叉排序树,其中每个结点的左子树和右子树的高度差至多等于1。
它是一种高度平衡的二叉排序树。现二叉平衡树结点定义如下:

typedef struct node
{int val;struct node *left;struct node *right;struct node *parent;int height;
} node_t;

请实现平衡二叉树的插入算法:

向根为 root 的平衡二叉树插入新元素 val,成功后返回新平衡二叉树根结点

node_t *avl_insert(node_t *root, int val);#include <stdlib.h>
#include <stdio.h>
#include "avl.h"int get_height(node_t *p){if(!p)return 0;elsereturn p->height;
}

示例代码如下:

一定要超级仔细, 不然绝对后悔!


node_t* avl_insert(node_t *root, int val){
//首先清晰字母定义;
//val新插入结点元素值,height高度!!!
//定义查找过程中出现的距离插入结点最近的平衡因子不为零的结点A
//定义A的孩子结点为B,需要旋转的结点
//定义插入节点为s,s的值为val
//平衡因子:左子树减去右子树深度 node_t *s, *A, *B, *C, *p, *fp;//依次:插入点, 失衡点(也可能是旋转点),旋转点,旋转点(也可能是插入点=s),动点,跟踪点int i, k;//平衡因子 s = (node_t *)malloc(sizeof(node_t));if(!s) return NULL;s->val = val;s->left = s->parent = s->right = NULL;s->height = 1;//类似于指针跟踪技术,p为动指针,A为跟踪指针 A = root; A->parent = NULL;p = root; p->parent = NULL;//找出A if(!p)root = s;else{while(p){//先找出最近的A->height!=0的结点, 就是最后的失衡点i = get_height(p->left) - get_height(p->right); if(i){A = p;A->parent = p->parent;}//fp跟踪p,因为下一步p会往下移动,p最终指向s的那一层 fp = p;if(val < p->val)p = p->left;elsep = p->right;}//p最终指向NULL就推出循环  } //插入, 此时fp是p的前一个结点,p指向空 if(val < fp->val)fp->left = s;elsefp->right = s;//确定旋转结点B,修改A的平衡因子if(val < A->val)B = A->left;elseB = A->right;A->height++;//修改路径B到s的高度, B在A的下一层 p = B; // p最终指向s, 之前指向的是s这一层,但是是空while(p != s){p->height++;if(val < p->val)p = p->left; elsep = p->right; }//最终s的高度没有++的 //调整完高度就修改结点和指针, 首先需要判断失衡类型//分为LL,LR,RR,RL//结点A,B平衡因子在修改指针的过程中会变化,但是路径上的结点不会//指针修改包括s结点指针和原来双亲结点指针 i = get_height(A->left) - get_height(A->right);k = get_height(B->left) - get_height(B->right); if(i == 2 && k == 1){//LL//B作为旋转结点//先改结点指针, 此时s插入在B的左子树下, 原来可以认为B左右子树,A右子树均为空A->left = B->right;B->right = A;//考虑原来A结点的指针,改成B后相应的指针也要改变,下面同理if(A->parent == NULL)root = B;else if(A->parent->left == A)A->parent->left = B;elseA->parent->right = B;        }else if(i == -2 && k == -1){//RRA->right = B->left;B->left = A;if(A->parent == NULL)root = B;else if(A->parent->left == A)A->parent->left = B;elseA->parent->right = B; }else if(i == 2 && k == -1){//LR//此时认为C的左右子树空,B逆时针旋转,A顺时针旋转, s插入C的左子树或者右子树 //如果C结点也是空,也就是说B右子树空,那么直接插入C=s为B右子树,此时A右子树也是空的 C = B->right;B->right = C->left;A->left = C->right;C->left = B;C->right = A;if(A->parent == NULL)root = C;else if(A->parent->left == A)A->parent->left = C;elseA->parent->right = C;}else if(i == -2 && k == 1){//RL //和LR一样,画图来看就好C = B->left;A->right = C->left;B->left = C->right;C->left = A;C->right = B;if(A->parent == NULL)root = C;else if(A->parent->left == A)A->parent->left = C;elseA->parent->right = C;}return root;
}

AVL添加平衡二叉树,是一种二叉排序树,其中每个结点的左子树和右子树的高度差至多等于1。-icoding-数据结构-C-typedef struct node{ int val;相关推荐

  1. SQL的几种连接:内连接、左联接、右连接、全连接、交叉连接

    作者:初行 – 博客园 SQL连接可以分为内连接.外连接.交叉连接. 数据库数据: book表:                                         stu表:       ...

  2. 入门二叉树,三种遍历,计算结点个数 ,深度 叶子结点个数,第k层结点个数

    1.关于二叉树的前中后序快速排序 那就在这里拿这张图来演示一下怎样快速写出中序遍历,我们都知道中序遍历是,左子树,根,右子树 B A C D E F H 最后直接得出结果DBEHACF 2.二叉树的五 ...

  3. 完全二叉树、平衡二叉树、二叉查找树(二叉排序树)

    完全二叉树 完全二叉树是一种特殊的二叉树,满足以下要求: 所有叶子节点都出现在 k 或者 k-1 层,而且从 1 到 k-1 层必须达到最大节点数: 第 k 层可以不是满的,但是第 k 层的所有节点必 ...

  4. AVL树(平衡二叉树)讲解,入门篇,适合新手观看

    1.1 概念 平衡二叉树就是为了让二叉搜索树的平均查找长度更短,时间复杂度更靠近logN,如果一个二叉搜索树不平衡了就会出现图1情况,完全变成一个数组,时间复杂度也变为了O(N). 平衡因子:平衡因子 ...

  5. 浅析平衡二叉树的四种旋转

    浅析平衡二叉树的四种旋转 二叉树: 1.若左子树不空,则左子树上所有节点的值均小于它的根节点的值: 2.若右子树不空,则右子树上所有节点的值均大于它的根节点的值: 3.左.右子树也分别为二叉排序树: ...

  6. AVL树添加节点后的平衡操作(一)逻辑分析:左旋、右旋、双旋(超详细图解)

    AVL树 AVL树是最早发明的自平衡二叉搜索树之一,其名字来源于两位发明它的科学家G. M. Adelson-Velsky 和 E. M. Landis(来自苏联的科学家). AVL树的特点 AVL树 ...

  7. 笛卡尔树 (25 分)笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字

    立志用最少的代码做最高效的表达 笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2.首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大.其次所有结点的 ...

  8. Suzy找到实习了吗Day 17 | 二叉树进行中:110. 平衡二叉树,257 二叉树的所有路径,404. 左叶子之和

    110. 平衡二叉树 题目 判断一颗二叉树是否是平和二叉树:一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 . 我的错误trial 我通过写了一个函数(后序遍历 ...

  9. 详细剖析平衡二叉树的四种旋转(附C++代码)

    经过一天的学习,笔者发现网上少有人剖析平衡二叉树为何要分为四种旋转情况(尤其是LR型和RL型旋转),学习起来感觉云里雾里.查阅相关资料后,笔者整理了以下几种解释,其中夹杂着笔者自己的理解(笔者也是初学 ...

最新文章

  1. PointRCNN: 点云的3D目标生成与检测
  2. 适用于Linux命令的10个R函数
  3. 从1G到5G,从回顾过去到展望未来
  4. python学习笔记3-循环1
  5. ThreadPoolExecutor的一点理解 专题
  6. C++将派生类赋值给基类(向上转型)(一)
  7. python递归深度报错--RuntimeError: maximum recursion depth exceeded
  8. Mac下安装及使用rz、sz远程上传下载文件
  9. 北京XXX学院WLAN项目现场勘查报告
  10. Python实现Adaboost
  11. 在Hyper-v中创建并安装虚拟机
  12. Python面向对象编程三大特性之继承
  13. c语言代码出来在哪里运行,C语言代码,怎么运行。
  14. Eucalyptus环境搭建
  15. CUDA核函数的实现——矩阵卷积
  16. mysql航空公司订票系统_航空订票系统(JAVA+SSH+MYSQL)
  17. 人工智能 猴子摘香蕉问题
  18. Kotlin协成的简单理解
  19. c语言 申请变量函数,C语言中变量和函数
  20. Mars3D中模型加载慢的优化办法

热门文章

  1. Thinkphp5.0 阿里云OSS扩展类上传示例(轮子)
  2. 找不到libmmd.dll无法继续执行代码_300 行代码带你秒懂 Java 多线程!| 原力计划...
  3. linux+arch系统下载,Linux
  4. modbus调试工具 linux,linux libmodbus的移植
  5. java ftp 判断目录存在_java判断ftp目录是否存在的方法
  6. jmeter聚个报告怎么看qps_Jmeter 使用笔记之 html 报告扩展(一)
  7. android管理activity顺序,android activity 六个主要函数以及一些调用顺序
  8. 线性跟驰模型 matlab,Bierley非线性跟驰模型特性仿真分析
  9. ORACLE数据加载加本,使用oracle sqlldr加载数据
  10. oracle未找到时区,Oracle ADF 未找到时区错误