stl 分析之 stl_tree.h

本文档详细介绍了STL中红黑树的实现,包括节点定义、迭代器操作、旋转和平衡算法等。红黑树是一种自平衡的二叉查找树,用于在关联容器如set和map中提供高效的数据操作。文档中展示了插入、删除和查找等操作的内部细节。
摘要由CSDN通过智能技术生成

 

/*

 *

 * Copyright (c) 1996,1997

 * Silicon Graphics Computer Systems, Inc.

 *

 * Permission to use, copy, modify, distribute and sell this software

 * and its documentation for any purpose is hereby granted without fee,

 * provided that the above copyright notice appear in all copies and

 * that both that copyright notice and this permission notice appear

 * in supporting documentation.  Silicon Graphics makes no

 * representations about the suitability of this software for any

 * purpose.  It is provided "as is" without express or implied warranty.

 *

 *

 * Copyright (c) 1994

 * Hewlett-Packard Company

 *

 * Permission to use, copy, modify, distribute and sell this software

 * and its documentation for any purpose is hereby granted without fee,

 * provided that the above copyright notice appear in all copies and

 * that both that copyright notice and this permission notice appear

 * in supporting documentation.  Hewlett-Packard Company makes no

 * representations about the suitability of this software for any

 * purpose.  It is provided "as is" without express or implied warranty.

 *

 *

 */

 

/* NOTE: This is an internal header file, included by other STL headers.

 *   You should not attempt to use it directly.

 */

 

#ifndef __SGI_STL_INTERNAL_TREE_H

#define __SGI_STL_INTERNAL_TREE_H

 

/*

 

Red-black tree class, designed for use in implementing STL

associative containers (set, multiset, map, and multimap). The

insertion and deletion algorithms are based on those in Cormen,

Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),

except that

 

(1) the header cell is maintained with links not only to the root

but also to the leftmost node of the tree, to enable constant time

begin(), and to the rightmost node of the tree, to enable linear time

performance when used with the generic set algorithms (set_union,

etc.);

 

(2) when a node being deleted has two children its successor node is

relinked into its place, rather than copied, so that the only

iterators invalidated are those referring to the deleted node.

 

*/

 

#include <stl_algobase.h>

#include <stl_alloc.h>

#include <stl_construct.h>

#include <stl_function.h>

 

__STL_BEGIN_NAMESPACE 

 

typedef bool __rb_tree_color_type;

const __rb_tree_color_type __rb_tree_red = false;

const __rb_tree_color_type __rb_tree_black = true;

 

struct __rb_tree_node_base

{

  typedef __rb_tree_color_type color_type;

  typedef __rb_tree_node_base* base_ptr;

 

  color_type color; 

  base_ptr parent;

  base_ptr left;

  base_ptr right;

 

  static base_ptr minimum(base_ptr x)

  {

    while (x->left != 0) x = x->left;

    return x;

  }

 

  static base_ptr maximum(base_ptr x)

  {

    while (x->right != 0) x = x->right;

    return x;

  }

};

 

template <class Value>

struct __rb_tree_node : public __rb_tree_node_base

{

  typedef __rb_tree_node<Value>* link_type;

  Value value_field;

};

 

//这里面只定义了一个node

//这个节点的类型为base_ptr(__rb_tree_node_base::base_ptr为__rb_tree_node_base里面的成员)

//实际上就是__rb_tree_node_base*

struct __rb_tree_base_iterator

{

  typedef __rb_tree_node_base::base_ptr base_ptr;

  typedef bidirectional_iterator_tag iterator_category;

  typedef ptrdiff_t difference_type;

  base_ptr node;

 

//返回下一个节点(该节点是红黑树中比当前节点大的第一个节点)

  void increment()

  {

   //有右孩子

    if (node->right != 0) {

      node = node->right;

      //找最左边的左孩子

      while (node->left != 0)

        node = node->left;

    }

    else { //右孩子为空

      base_ptr y = node->parent;

      while (node == y->right) {

        node = y;

        y = y->parent;

      }

      if (node->right != y)

        node = y;

    }

  }

 

  void decrement()

  {

    if (node->color == __rb_tree_red &&

        node->parent->parent == node)

      node = node->right;

    else if (node->left != 0) {

      base_ptr y = node->left;

      while (y->right != 0)

        y = y->right;

      node = y;

    }

    else {

      base_ptr y = node->parent;

      while (node == y->left) {

        node = y;

        y = y->parent;

      }

      node = y;

    }

  }

};

 

template <class Value, class Ref, class Ptr>

struct __rb_tree_iterator : public __rb_tree_base_iterator

{

  typedef Value value_type;

  typedef Ref reference;

  typedef Ptr pointer;

  typedef __rb_tree_iterator<Value, Value&, Value*>             iterator;

  typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator;

  typedef __rb_tree_iterator<Value, Ref, Ptr>                   self;

  typedef __rb_tree_node<Value>* link_type;

 

  __rb_tree_iterator() {}

  __rb_tree_iterator(link_type x) { node = x; }

  __rb_tree_iterator(const iterator& it) { node = it.node; }

 

  reference operator*() const { return link_type(node)->value_field; }

#ifndef __SGI_STL_NO_ARROW_OPERATOR

  pointer operator->() const { return &(operator*()); }

#endif /* __SGI_STL_NO_ARROW_OPERATOR */

 

  self& operator++() { increment(); return *this; }

  self operator++(int) {

    self tmp = *this;

    increment();

    return tmp;

  }

 

  self& operator--() { decrement(); return *this; }

  self operator--(int) {

    self tmp = *this;

    decrement();

    return tmp;

  }

};

 

inline bool operator==(const __rb_tree_base_iterator& x,

                       const __rb_tree_base_iterator& y) {

  return x.node == y.node;

}

 

inline bool operator!=(const __rb_tree_base_iterator& x,

                       const __rb_tree_base_iterator& y) {

  return x.node != y.node;

}

 

#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION

 

inline bidirectional_iterator_tag

iterator_category(const __rb_tree_base_iterator&) {

  return bidirectional_iterator_tag();

}

 

inline __rb_tree_base_iterator::difference_type*

distance_type(const __rb_tree_base_iterator&) {

  return (__rb_tree_base_iterator::difference_type*) 0;

}

 

template <class Value, class Ref, class Ptr>

inline Value* value_type(const __rb_tree_iterator<Value, Ref, Ptr>&) {

  return (Value*) 0;

}

 

#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */

 

//向左旋转

//注意的一点是:有个父亲节点需要设置

inline void 

__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root)

{

  __rb_tree_node_base* y = x->right;

  x->right = y->left;

  if (y->left !=0)

    y->left->parent = x;

  y->parent = x->parent;

 

  if (x == root) //如果x自己本身是root节点,那么现在的root节点应该变成y(x的右孩子了)

    root = y;

  else if (x == x->parent->left) //如果x自己是(自己父亲的)左孩子,那么现在他父亲的左孩子应该是y了

    x->parent->left = y;

  else //如果x自己是右孩子,那么现在他父亲的右孩子应该是y

    x->parent->right = y;

  y->left = x; //让x的右孩子占了x的位置。

  x->parent = y;

}

 

inline void 

__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root)

{

  __rb_tree_node_base* y = x->left;

  x->left = y->right;

  if (y->right != 0)

    y->right->parent = x;

  y->parent = x->parent;

 

  if (x == root)

    root = y;

  else if (x == x->parent->right)

    x->parent->right = y;

  else

    x->parent->left = y;

  y->right = x;

  x->parent = y;

}

 

inline void 

__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root)

{

  x->color = __rb_tree_red;

  while (x != root && x->parent->

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值