AVL平衡二叉树,数据结构图文解析之:AVL树详解及C++模板实现

一.AVL简介

AVL树的名字来源于它的发明作者G.M. Adelson-Velsky 和 E.M. Landis。AVL树是最先发明的自平衡二叉查找树(Self-Balancing Binary Search Tree,简称平衡二叉树)。

AVL树又称平衡二叉搜索树,它能保证二叉树高度相对平衡,尽量降低二叉树的高度,提高搜索效率。单纯的二叉搜索树在最坏的情况下插入查找删除等操作时间复杂度会是O(N),AVL树使得增删查改的时间复杂度为O(lgN). (ps:这里的lgN指的是log以2为底的N)

AVL树特点:

1. 左子树和右子树的高度之差的绝对值不超过1。  2. 树中的每个左子树和右子树都是AVL树。 3. 每个节点都有一个平衡因子(balance factor–bf),任一节点的平衡因子是-1,0,1。
平衡因子:将二叉树上节点的左子树高度减去右子树高度的值称为该节点的平衡因子BF(Balance Factor)。

二. AVL理论

   

三. AVL实现

C语言的实现部分参考openwrt的libubox。

1. 节点node

struct avl_node {
  /**
   * Linked list node for supporting easy iteration and multiple
   * elments with the same key.
   *
   * this must be the first element of an avl_node to
   * make casting for lists easier
   */
  struct list_head list;

  /**
   * Pointer to parent node in tree, NULL if root node
   */
  struct avl_node *parent;

  /**
   * Pointer to left child
   */
  struct avl_node *left;

  /**
   * Pointer to right child
   */
  struct avl_node *right;

  /**
   * pointer to key of node
   */
  const void *key;

  /**
   * balance state of AVL tree (0,-1,+1)
   */
  signed char balance;

  /**
   * true if first of a series of nodes with same key
   */
  bool leader;
};

2. AVL树

struct avl_tree {
  /**
   * Head of linked list node for supporting easy iteration
   * and multiple elments with the same key.
   */
  struct list_head list_head;

  /**
   * pointer to the root node of the avl tree, NULL if tree is empty
   */
  struct avl_node *root;

  /**
   * number of nodes in the avl tree
   */
  unsigned int count;

  /**
   * true if multiple nodes with the same key are
   * allowed in the tree, false otherwise
   */
  bool allow_dups;

  /**
   * pointer to the tree comparator
   *
   * First two parameters are keys to compare,
   * third parameter is a copy of cmp_ptr
   */
  avl_tree_comp comp;

  /**
   * custom pointer delivered to the tree comparator
   */
  void *cmp_ptr;
};
/**
 * Prototype for avl comparators
 * @param k1 first key
 * @param k2 second key
 * @param ptr custom data for tree comparator
 * @return +1 if k1>k2, -1 if k1<k2, 0 if k1==k2
 */
typedef int (*avl_tree_comp) (const void *k1, const void *k2, void *ptr);

 3. alv树初始化

void avl_init(struct avl_tree *tree, avl_tree_comp comp, bool allow_dups, void *ptr)
{
  INIT_LIST_HEAD(&tree->list_head);
  tree->root = NULL;
  tree->count = 0;
  tree->comp = comp;
  tree->allow_dups = allow_dups;
  tree->cmp_ptr = ptr;
}
#define AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr)  \
    {                           \
        .list_head = LIST_HEAD_INIT(_name.list_head),   \
        .comp = _comp,                  \
        .allow_dups = _allow_dups,          \
        .cmp_ptr = _cmp_ptr             \
    }

#define AVL_TREE(_name, _comp, _allow_dups, _cmp_ptr)       \
    struct avl_tree _name =                 \
        AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr)

4. avl树增加节点

/**
 * Inserts an avl_node into a tree
 * @param tree pointer to tree
 * @param new pointer to node
 * @return 0 if node was inserted successfully, -1 if it was not inserted
 *   because of a key collision
 */
int avl_insert(struct avl_tree *tree, struct avl_node *new)
{
  struct avl_node *node, *next, *last;
  int diff;

  new->parent = NULL;

  new->left = NULL;
  new->right = NULL;

  new->balance = 0;
  new->leader = true;

  if (tree->root == NULL) {
    list_add(&new->list, &tree->list_head);
    tree->root = new;
    tree->count = 1;
    return 0;
  }

  node = avl_find_rec(tree->root, new->key, tree->comp, tree->cmp_ptr, &diff);

  last = node;
  while (!list_is_last(&last->list, &tree->list_head)) {
    next = avl_next(last);
    if (next->leader) {
      break;
    }
    last = next;
  }

  diff = (*tree->comp) (new->key, node->key, tree->cmp_ptr);

  if (diff == 0) {
    if (!tree->allow_dups)
      return -1;

    new->leader = 0;

    avl_insert_after(tree, last, new);
    return 0;
  }

  if (node->balance == 1) {
    avl_insert_before(tree, node, new);

    node->balance = 0;
    new->parent = node;
    node->left = new;
    return 0;
  }

  if (node->balance == -1) {
    avl_insert_after(tree, last, new);

    node->balance = 0;
    new->parent = node;
    node->right = new;
    return 0;
  }
  if (diff < 0) {
    avl_insert_before(tree, node, new);

    node->balance = -1;
    new->parent = node;
    node->left = new;
    post_insert(tree, node);
    return 0;
  }

  avl_insert_after(tree, last, new);

  node->balance = 1;
  new->parent = node;
  node->right = new;
  post_insert(tree, node);
  return 0;
}

5. avl树删除节点

void avl_delete(struct avl_tree *tree, struct avl_node *node)
{ 
  struct avl_node *next;
  struct avl_node *parent;
  struct avl_node *left;
  struct avl_node *right;
  if (node->leader) {
    if (tree->allow_dups
        && !list_is_last(&node->list, &tree->list_head)
        && !(next = avl_next(node))->leader) {
      next->leader = true;
      next->balance = node->balance;
      
      parent = node->parent;
      left = node->left;
      right = node->right;
      
      next->parent = parent;
      next->left = left;
      next->right = right;
      
      if (parent == NULL)
        tree->root = next;
      
      else {
        if (node == parent->left)
          parent->left = next;
        
        else
          parent->right = next;
      }
      
      if (left != NULL)
        left->parent = next;
      
      if (right != NULL)
        right->parent = next;
    }
    
    else
      avl_delete_worker(tree, node);
  }
  
  avl_remove(tree, node);
} 

6. avl树查找节点

struct avl_node *EXPORT(avl_find)(const struct avl_tree *, const void *key);
struct avl_node *EXPORT(avl_find_greaterequal)(const struct avl_tree *tree, const void *key);
struct avl_node *EXPORT(avl_find_lessequal)(const struct avl_tree *tree, const void *key);
static inline bool
avl_is_first(struct avl_tree *tree, struct avl_node *node) {
  return tree->list_head.next == &node->list;
}

static inline bool
avl_is_last(struct avl_tree *tree, struct avl_node *node) {
  return tree->list_head.prev == &node->list;
}

static inline bool
avl_is_empty(struct avl_tree *tree) {
  return tree->count == 0;
}
static inline void *
__avl_find_element(const struct avl_tree *tree, const void *key, size_t offset, enum avl_find_mode mode) {
  void *node = NULL;

  switch (mode) {
    case AVL_FIND_EQUAL:
      node = avl_find(tree, key);
      break;
    case AVL_FIND_LESSEQUAL:
      node = avl_find_lessequal(tree, key);
      break;
    case AVL_FIND_GREATEREQUAL:
      node = avl_find_greaterequal(tree, key);
      break;
  }
  return node == NULL ? NULL : (((char *)node) - offset);
}

#define avl_find_element(tree, key, element, node_element) \
  ((typeof(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_EQUAL))
#define avl_find_le_element(tree, key, element, node_element) \
  ((typeof(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_LESSEQUAL))
#define avl_find_ge_element(tree, key, element, node_element) \
  ((typeof(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_GREATEREQUAL))
#define avl_first_element(tree, element, node_member) \
  container_of((tree)->list_head.next, typeof(*(element)), node_member.list)
#define avl_last_element(tree, element, node_member) \
  container_of((tree)->list_head.prev, typeof(*(element)), node_member.list)
#define avl_next_element(element, node_member) \
  container_of((&(element)->node_member.list)->next, typeof(*(element)), node_member.list)
#define avl_prev_element(element, node_member) \
  container_of((&(element)->node_member.list)->prev, typeof(*(element)), node_member.list)
#define avl_for_element_range(first, last, element, node_member) \
  for (element = (first); \
       element->node_member.list.prev != &(last)->node_member.list; \
       element = avl_next_element(element, node_member))
#define avl_for_element_range_reverse(first, last, element, node_member) \
  for (element = (last); \
       element->node_member.list.next != &(first)->node_member.list; \
       element = avl_prev_element(element, node_member))
#define avl_for_each_element(tree, element, node_member) \
  avl_for_element_range(avl_first_element(tree, element, node_member), \
                        avl_last_element(tree, element,  node_member), \
                        element, node_member)
#define avl_for_each_element_reverse(tree, element, node_member) \
  avl_for_element_range_reverse(avl_first_element(tree, element, node_member), \
                                avl_last_element(tree, element,  node_member), \
                                element, node_member)
#define avl_for_element_to_last(tree, first, element, node_member) \
  avl_for_element_range(first, avl_last_element(tree, element, node_member), element, node_member)
#define avl_for_element_to_last_reverse(tree, first, element, node_member) \
  avl_for_element_range_reverse(first, avl_last_element(tree, element, node_member), element, node_member)
#define avl_for_first_to_element(tree, last, element, node_member) \
  avl_for_element_range(avl_first_element(tree, element, node_member), last, element, node_member)
#define avl_for_first_to_element_reverse(tree, last, element, node_member) \
  avl_for_element_range_reverse(avl_first_element(tree, element, node_member), last, element, node_member)

完整代码参考:http://git.openwrt.org/project/libubox.git

 

参考:

1. 【数据结构】AVL树详解

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

3. 数据结构学习之二叉树(理论篇)

4. 数据结构学习之二叉树(实践篇)

    原文作者:yuxi_o
    原文地址: https://www.cnblogs.com/embedded-linux/p/9193038.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞