⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avltree.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2008 Apple Inc. All rights reserved. * * Based on Abstract AVL Tree Template v1.5 by Walt Karas * <http://geocities.com/wkaras/gen_cpp/avl_tree.html>. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1.  Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer. * 2.  Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution. * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#ifndef AVL_TREE_H_#define AVL_TREE_H_#include "Assertions.h"namespace WTF {// Here is the reference class for BSet.//// class BSet//   {//   public:////     class ANY_bitref//       {//       public://         operator bool ();//         void operator = (bool b);//       };////     // Does not have to initialize bits.//     BSet();////     // Must return a valid value for index when 0 <= index < maxDepth//     ANY_bitref operator [] (unsigned index);////     // Set all bits to 1.//     void set();////     // Set all bits to 0.//     void reset();//   };template<unsigned maxDepth>class AVLTreeDefaultBSet {public:    bool& operator[](unsigned i) { ASSERT(i < maxDepth); return m_data[i]; }    void set() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = true; }    void reset() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = false; }private:    bool m_data[maxDepth];};// How to determine maxDepth:// d  Minimum number of nodes// 2  2// 3  4// 4  7// 5  12// 6  20// 7  33// 8  54// 9  88// 10 143// 11 232// 12 376// 13 609// 14 986// 15 1,596// 16 2,583// 17 4,180// 18 6,764// 19 10,945// 20 17,710// 21 28,656// 22 46,367// 23 75,024// 24 121,392// 25 196,417// 26 317,810// 27 514,228// 28 832,039// 29 1,346,268// 30 2,178,308// 31 3,524,577// 32 5,702,886// 33 9,227,464// 34 14,930,351// 35 24,157,816// 36 39,088,168// 37 63,245,985// 38 102,334,154// 39 165,580,140// 40 267,914,295// 41 433,494,436// 42 701,408,732// 43 1,134,903,169// 44 1,836,311,902// 45 2,971,215,072//// E.g., if, in a particular instantiation, the maximum number of nodes in a tree instance is 1,000,000, the maximum depth should be 28.// You pick 28 because MN(28) is 832,039, which is less than or equal to 1,000,000, and MN(29) is 1,346,268, which is strictly greater than 1,000,000.template <class Abstractor, unsigned maxDepth = 32, class BSet = AVLTreeDefaultBSet<maxDepth> >class AVLTree {public:    typedef typename Abstractor::key key;    typedef typename Abstractor::handle handle;    typedef typename Abstractor::size size;    enum SearchType {        EQUAL = 1,        LESS = 2,        GREATER = 4,        LESS_EQUAL = EQUAL | LESS,        GREATER_EQUAL = EQUAL | GREATER    };    Abstractor& abstractor() { return abs; }    inline handle insert(handle h);    inline handle search(key k, SearchType st = EQUAL);    inline handle search_least();    inline handle search_greatest();    inline handle remove(key k);    inline handle subst(handle new_node);    void purge() { abs.root = null(); }    bool is_empty() { return abs.root == null(); }    AVLTree() { abs.root = null(); }    class Iterator {    public:        // Initialize depth to invalid value, to indicate iterator is        // invalid.   (Depth is zero-base.)        Iterator() { depth = ~0U; }        void start_iter(AVLTree &tree, key k, SearchType st = EQUAL)        {            // Mask of high bit in an int.            const int MASK_HIGH_BIT = (int) ~ ((~ (unsigned) 0) >> 1);            // Save the tree that we're going to iterate through in a            // member variable.            tree_ = &tree;            int cmp, target_cmp;            handle h = tree_->abs.root;            unsigned d = 0;            depth = ~0U;            if (h == null())              // Tree is empty.              return;            if (st & LESS)              // Key can be greater than key of starting node.              target_cmp = 1;            else if (st & GREATER)              // Key can be less than key of starting node.              target_cmp = -1;            else              // Key must be same as key of starting node.              target_cmp = 0;            for (;;) {                cmp = cmp_k_n(k, h);                if (cmp == 0) {                    if (st & EQUAL) {                        // Equal node was sought and found as starting node.                        depth = d;                        break;                    }                    cmp = -target_cmp;                } else if (target_cmp != 0) {                    if (!((cmp ^ target_cmp) & MASK_HIGH_BIT)) {                        // cmp and target_cmp are both negative or both positive.                        depth = d;                    }                }                h = cmp < 0 ? get_lt(h) : get_gt(h);                if (h == null())                    break;                branch[d] = cmp > 0;                path_h[d++] = h;            }        }        void start_iter_least(AVLTree &tree)        {            tree_ = &tree;            handle h = tree_->abs.root;            depth = ~0U;            branch.reset();            while (h != null()) {                if (depth != ~0U)                    path_h[depth] = h;                depth++;                h = get_lt(h);            }        }        void start_iter_greatest(AVLTree &tree)        {            tree_ = &tree;            handle h = tree_->abs.root;            depth = ~0U;            branch.set();            while (h != null()) {                if (depth != ~0U)                    path_h[depth] = h;                depth++;                h = get_gt(h);            }        }        handle operator*()        {            if (depth == ~0U)                return null();            return depth == 0 ? tree_->abs.root : path_h[depth - 1];        }        void operator++()        {            if (depth != ~0U) {                handle h = get_gt(**this);                if (h == null()) {                    do {                        if (depth == 0) {                            depth = ~0U;                            break;                        }                        depth--;                    } while (branch[depth]);                } else {                    branch[depth] = true;                    path_h[depth++] = h;                    for (;;) {                        h = get_lt(h);                        if (h == null())                            break;                        branch[depth] = false;                        path_h[depth++] = h;                    }                }            }        }        void operator--()        {            if (depth != ~0U) {                handle h = get_lt(**this);                if (h == null())                    do {                        if (depth == 0) {                            depth = ~0U;                            break;                        }                        depth--;                    } while (!branch[depth]);                else {                    branch[depth] = false;                    path_h[depth++] = h;                    for (;;) {                        h = get_gt(h);                        if (h == null())                            break;                        branch[depth] = true;                        path_h[depth++] = h;                    }                }            }        }        void operator++(int) { ++(*this); }        void operator--(int) { --(*this); }    protected:        // Tree being iterated over.        AVLTree *tree_;        // Records a path into the tree.  If branch[n] is true, indicates        // take greater branch from the nth node in the path, otherwise        // take the less branch.  branch[0] gives branch from root, and        // so on.        BSet branch;        // Zero-based depth of path into tree.        unsigned depth;        // Handles of nodes in path from root to current node (returned by *).        handle path_h[maxDepth - 1];        int cmp_k_n(key k, handle h) { return tree_->abs.compare_key_node(k, h); }        int cmp_n_n(handle h1, handle h2) { return tree_->abs.compare_node_node(h1, h2); }        handle get_lt(handle h) { return tree_->abs.get_less(h); }        handle get_gt(handle h) { return tree_->abs.get_greater(h); }        handle null() { return tree_->abs.null(); }    };    template<typename fwd_iter>    bool build(fwd_iter p, size num_nodes)    {        if (num_nodes == 0) {            abs.root = null();            return true;        }        // Gives path to subtree being built.  If branch[N] is false, branch        // less from the node at depth N, if true branch greater.        BSet branch;        // If rem[N] is true, then for the current subtree at depth N, it's        // greater subtree has one more node than it's less subtree.        BSet rem;            // Depth of root node of current subtree.        unsigned depth = 0;            // Number of nodes in current subtree.        size num_sub = num_nodes;        // The algorithm relies on a stack of nodes whose less subtree has        // been built, but whose right subtree has not yet been built.  The        // stack is implemented as linked list.  The nodes are linked        // together by having the "greater" handle of a node set to the        // next node in the list.  "less_parent" is the handle of the first        // node in the list.        handle less_parent = null();        // h is root of current subtree, child is one of its children.        handle h, child;        for (;;) {            while (num_sub > 2) {                // Subtract one for root of subtree.                num_sub--;                rem[depth] = !!(num_sub & 1);                branch[depth++] = false;                num_sub >>= 1;            }            if (num_sub == 2) {                // Build a subtree with two nodes, slanting to greater.                // I arbitrarily chose to always have the extra node in the                // greater subtree when there is an odd number of nodes to                // split between the two subtrees.                h = *p;                p++;                child = *p;                p++;                set_lt(child, null());                set_gt(child, null());                set_bf(child, 0);                set_gt(h, child);                set_lt(h, null());                set_bf(h, 1);            } else { // num_sub == 1                // Build a subtree with one node.                h = *p;                p++;                set_lt(h, null());                set_gt(h, null());                set_bf(h, 0);            }            while (depth) {                depth--;                if (!branch[depth])                    // We've completed a less subtree.                    break;                // We've completed a greater subtree, so attach it to                // its parent (that is less than it).  We pop the parent                // off the stack of less parents.                child = h;                h = less_parent;                less_parent = get_gt(h);                set_gt(h, child);                // num_sub = 2 * (num_sub - rem[depth]) + rem[depth] + 1                num_sub <<= 1;                num_sub += 1 - rem[depth];                if (num_sub & (num_sub - 1))                    // num_sub is not a power of 2                    set_bf(h, 0);                else                    // num_sub is a power of 2                    set_bf(h, 1);            }            if (num_sub == num_nodes)                // We've completed the full tree.                break;            // The subtree we've completed is the less subtree of the            // next node in the sequence.            child = h;            h = *p;            p++;            set_lt(h, child);            // Put h into stack of less parents.            set_gt(h, less_parent);            less_parent = h;            // Proceed to creating greater than subtree of h.            branch[depth] = true;            num_sub += rem[depth++];        } // end for (;;)        abs.root = h;        return true;    }protected:    friend class Iterator;    // Create a class whose sole purpose is to take advantage of    // the "empty member" optimization.    struct abs_plus_root : public Abstractor {        // The handle of the root element in the AVL tree.        handle root;    };    abs_plus_root abs;    handle get_lt(handle h) { return abs.get_less(h); }    void set_lt(handle h, handle lh) { abs.set_less(h, lh); }    handle get_gt(handle h) { return abs.get_greater(h); }    void set_gt(handle h, handle gh) { abs.set_greater(h, gh); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -