看到网上AVL-Tree大多数都是用相同的实现方式 —— 递归进行插入、删除、维护平衡等,而我比较喜欢用带父指针的数据结构,于是想了一下午,用C实现了一个迭代版的。

  由于没有暂时没有好的画二叉树的工具,所以暂时不做详细解释了(没有配图实在没说服力)。

  目前发现graphviz还行,准备简单学一下,等有了配图再解释。

  代码:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h> #define max(a, b) ((a) > (b) ? (a) : (b)) typedef struct BaseNode {
int val;
int height;
struct BaseNode * left;
struct BaseNode * right;
struct BaseNode * parent;
} avl_tree; avl_tree* fixup_insert_avltree(avl_tree* root, avl_tree* node);
avl_tree* fixup_erase_avltree(avl_tree* root, avl_tree* node);
avl_tree* search(avl_tree* node, int x); void initializtion(avl_tree** root)
{
(*root) = NULL;
} int height(avl_tree* node)
{
if (node == NULL)
return -1;
else
return node->height;
} void fixup_height(avl_tree* node)
{
int LeftHeight = height(node->left);
int RightHeight = height(node->right); if (LeftHeight > RightHeight)
node->height = LeftHeight + 1;
else
node->height = RightHeight + 1;
} int balance(avl_tree* node)
{
if (node == NULL)
return 0;
else
return height(node->left) - height(node->right);
} avl_tree* parent(avl_tree * node)
{
if (node == NULL)
return NULL;
else
return node->parent;
} avl_tree* grandparent(avl_tree * node)
{
avl_tree* pptr = parent(node);
if (pptr == NULL)
return NULL;
else
return pptr->parent;
} avl_tree* left_rotate(avl_tree* root, avl_tree* node)
{
avl_tree * x = node;
avl_tree * y = node->right;
x->right = y->left;
if (y->left != NULL)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == NULL)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y; fixup_height(x);
fixup_height(y); return root;
} avl_tree* right_rotate(avl_tree* root, avl_tree* node)
{
avl_tree* x = node;
avl_tree* y = node->left;
x->left = y->right;
if (y->right != NULL)
y->right->parent = x;
y->parent = x->parent;
if (x->parent == NULL)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->right = x;
x->parent = y; fixup_height(x);
fixup_height(y); return root;
} avl_tree* left_right_rotate(avl_tree* root, avl_tree* node)
{
avl_tree * x = node;
avl_tree * y = node->left;
root = left_rotate(root, y);
root = right_rotate(root, x); return root;
} avl_tree* right_left_rotate(avl_tree* root, avl_tree* node)
{
avl_tree * x = node;
avl_tree * y = node->right;
root = right_rotate(root, y);
root = left_rotate(root, x); return root;
} void insert(avl_tree** root, int x)
{
avl_tree* nn = (avl_tree*)malloc(sizeof(avl_tree));
nn->left = nn->right = NULL;
nn->val = x;
nn->height = 0; avl_tree* p = (*root);
avl_tree* q = NULL;
while (p != NULL)
{
q = p;
if (p->val > x)
p = p->left;
else
p = p->right;
}
nn->parent = q; if (q == NULL)
(*root) = nn;
else if (q->val > x)
q->left = nn;
else
q->right = nn; avl_tree * temp = nn;
while (temp != NULL)
{
fixup_height(temp);
temp = temp->parent;
}
*root = fixup_insert_avltree(*root, nn);
} avl_tree* fixup_insert_avltree(avl_tree* root, avl_tree* node)
{
while (node != NULL)
{
avl_tree* gpptr = grandparent(node);
avl_tree* gppptr = parent(gpptr);
if ((balance(gpptr) > 1 || balance(gpptr) < -1))
{
if (parent(node) == gpptr->left && node == parent(node)->left)
root = right_rotate(root, gpptr);
else if (parent(node) == gpptr->left && node == parent(node)->right)
root = left_right_rotate(root, gpptr);
else if (parent(node) == gpptr->right && node == parent(node)->right)
root = left_rotate(root, gpptr);
else
root = right_left_rotate(root, gpptr); while (gppptr != NULL)
{
fixup_height(gppptr);
gppptr = gppptr->parent;
}
}
node = parent(node);
}
return root;
} avl_tree* get_min_node(avl_tree* node)
{
avl_tree* mnode = node;
if (mnode != NULL)
while (mnode->left != NULL)
mnode = mnode->left;
return mnode;
} avl_tree* get_max_node(avl_tree* node)
{
avl_tree* mnode = node;
if (mnode != NULL)
while (mnode->right != NULL)
mnode = mnode->right;
return mnode;
} avl_tree* transform(avl_tree* root, avl_tree* ernode, avl_tree* node)
{
if (ernode->parent == NULL)
root = node;
else if (ernode == parent(ernode)->left)
parent(ernode)->left = node;
else
parent(ernode)->right = node; if (node != NULL)
node->parent = parent(ernode); return root;
} void erase(avl_tree** root, int x)
{
avl_tree* node = search(*root, x);
avl_tree* nptr; if (node == NULL)
return ;
if (node->left == NULL)
{
nptr = parent(node);
*root = transform(*root, node, node->right);
}
else if (node->right == NULL)
{
nptr = parent(node);
*root = transform(*root, node, node->left);
}
else
{
avl_tree* mn = get_min_node(node->right);
if (parent(mn) == node)
nptr = mn;
else
{
nptr = parent(mn);
*root = transform(*root, mn, mn->right);
mn->right = node->right;
if (mn->right != NULL)
mn->right->parent = mn;
}
*root = transform(*root, node, mn);
mn->left = node->left;
if (mn->left != NULL)
mn->left->parent = mn;
} avl_tree* checknode = nptr;
while (checknode != NULL)
{
fixup_height(checknode);
checknode = checknode->parent;
} *root = fixup_erase_avltree(*root, nptr); free(node);
node = NULL;
} avl_tree* fixup_erase_avltree(avl_tree* root, avl_tree* node)
{
while (node != NULL)
{
if (balance(node) > 1)
{
if (balance(node->left) > 0)
root = right_rotate(root, node);
else
root = left_right_rotate(root, node);
}
else if (balance(node) < -1)
{
if (balance(node->right) < 0)
root = left_rotate(root, node);
else
root = right_left_rotate(root, node);
} node = node->parent;
if (node != NULL)
fixup_height(node);
}
return root;
} avl_tree* search(avl_tree* node, int x)
{
if (node == NULL)
return NULL;
else if (node->val > x)
return search(node->left, x);
else if (node->val < x)
return search(node->right, x);
else
return node;
} void inorder(avl_tree* node)
{
if (node == NULL)
{
inorder(node->left);
printf("%d ", node->val);
inorder(node->right);
}
} int degree(avl_tree* node)
{
if (node == NULL)
return 0;
return degree(node->left) + degree(node->right) + 1;
} int depth(avl_tree* node)
{
if (node == NULL)
return 0;
return max(depth(node->left), depth(node->right)) + 1;
} void checkbalance(avl_tree* node)
{
if (node == NULL)
{
checkbalance(node->left);
printf("%d --- 高度:%d --- 平衡度:%d\n", node->val, node->height, balance(node));
checkbalance(node->right);
}
} void destory(avl_tree** node)
{
if ((*node) != NULL)
{
destory(&(*node)->left);
destory(&(*node)->right);
free((*node));
}
} int main()
{
avl_tree* root, * node;
int x;
char ch; initializtion(&root); puts("1> 添加 2> 删除");
puts("3> 查找 4> 查看");
puts("5> 个数 6> 深度");
puts("7> 平衡 8> 退出"); while ((ch = getch()) != '8')
{
switch (ch)
{
case '1':
puts("输入:");
scanf("%d", &x);
insert(&root, x);
break;
case '2':
puts("输入:");
scanf("%d", &x);
erase(&root, x);
break;
case '3':
puts("输入:");
scanf("%d", &x);
if ((node = search(root, x)) != NULL)
printf("%d\n", node->val);
break;
case '4':
puts("显示数据:");
inorder(root);
printf("\n");
break;
case '5':
printf("\n当前数据个数:%d\n", degree(root));
break;
case '6':
printf("\n当前树深度:%d\n", depth(root));
break;
case '7':
puts("平衡检查:");
checkbalance(root);
break;
}
}
destory(&root);
return 0;
}

  

  

  

AVL-Tree (平衡二叉树)的更多相关文章

  1. PAT A1123 Is It a Complete AVL Tree (30 分)——AVL平衡二叉树,完全二叉树

    An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...

  2. 平衡二叉树(AVL Tree)

    在学习算法的过程中,二叉平衡树是一定会碰到的,这篇博文尽可能简明易懂的介绍下二叉树的相关概念,然后着重讲下什么事平衡二叉树. (由于作图的时候忽略了箭头的问题,正常的树一般没有箭头,虽然不影响描述的过 ...

  3. PAT 甲级 1066 Root of AVL Tree (25 分)(快速掌握平衡二叉树的旋转,内含代码和注解)***

    1066 Root of AVL Tree (25 分)   An AVL tree is a self-balancing binary search tree. In an AVL tree, t ...

  4. 转载:平衡二叉树(AVL Tree)

    平衡二叉树(AVL Tree) 转载至:https://www.cnblogs.com/jielongAI/p/9565776.html 在学习算法的过程中,二叉平衡树是一定会碰到的,这篇博文尽可能简 ...

  5. 04-树5 Root of AVL Tree

    平衡二叉树 LL RR LR RL 注意画图理解法 An AVL tree is a self-balancing binary search tree. In an AVL tree, the he ...

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

    一 什么是AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节 ...

  7. A1123. Is It a Complete AVL Tree

    An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...

  8. 04-树5 Root of AVL Tree + AVL树操作集

    平衡二叉树-课程视频 An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the tw ...

  9. PAT甲级1123. Is It a Complete AVL Tree

    PAT甲级1123. Is It a Complete AVL Tree 题意: 在AVL树中,任何节点的两个子树的高度最多有一个;如果在任何时候它们不同于一个,则重新平衡来恢复此属性.图1-4说明了 ...

  10. HDU 2193 AVL Tree

    AVL Tree An AVL tree is a kind of balanced binary search tree. Named after their inventors, Adelson- ...

随机推荐

  1. API接收数据反序列化失败问题查找

    C# API接收到数据后,反序列化后直接返回null,而不会给出错误提示,所以不好排查错误. 通过在api中直接进行反序列化,能够得到错误明细: 没有报错的时候,request会直接为null,不会报 ...

  2. 吴裕雄 PYTHON 人工智能——基于MASK_RCNN目标检测(5)

    import os import sys import numpy as np import tensorflow as tf import matplotlib import matplotlib. ...

  3. AMD R7 2700X 安装虚拟机

    自己组装的台式机,选用的是微星X470主板,该主板默认的虚拟化技术是关闭的,在bios中也不太容易找到,具体方法如下. [开机或重启]--[按住DEL进入BIOS]--[高级模式F7]--[选择OC] ...

  4. Java数组和方法

    1. 数组可以作为方法的参数 package cn.itcast.day05.demo04; /* 数组可以作为方法的参数. 当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值. ...

  5. SSIS部署后执行失败,无法将保护的XML节点解密

    将包属性中的 protectionLevel 设置成DontSaveSensitive 即可.

  6. Linux - 查看文件、文件夹、磁盘大小命令

    1. ls -lsh 2. du -sh du == disk usage (磁盘使用量,占用的磁盘空间) 一个文件占用的磁盘空间和一个文件的大小是两码事情.占用空间取决于文件系统的块(block)的 ...

  7. Linux 一些有用的能力

    编程能力 Linux产生于一群真正的黑客.尽管人们习惯于认为Linus是Linux的缔造者,在linux包含的数以千计的文件中,也有一个名为Credits的文件记录了主要的Linux Hacker们的 ...

  8. POJ-2891 Strange Way to Express Integers(拓展中国剩余定理)

    放一个写的不错的博客:https://www.cnblogs.com/zwfymqz/p/8425731.html POJ好像不能用__int128. #include <iostream> ...

  9. 样式计算的几种方式与兼容写法:getComputedStyle&currentStyle&style

    window.getComputedStyle(element,[string]) 1参为需要获取样式的元素,2参指定伪元素字符串(如“::after”,不需要则为null),设置2参可获取eleme ...

  10. java与以太坊之web3j

    web3j:https://docs.web3j.io/index.html 如何使用Web3j生成私钥和地址,而不只是创建密钥存储JSON文件? https://blog.csdn.net/mong ...