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

📄 avltree.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
📖 第 1 页 / 共 2 页
字号:
    int get_bf(handle h) { return abs.get_balance_factor(h); }    void set_bf(handle h, int bf) { abs.set_balance_factor(h, bf); }    int cmp_k_n(key k, handle h) { return abs.compare_key_node(k, h); }    int cmp_n_n(handle h1, handle h2) { return abs.compare_node_node(h1, h2); }    handle null() { return abs.null(); }private:    // Balances subtree, returns handle of root node of subtree    // after balancing.    handle balance(handle bal_h)    {        handle deep_h;        // Either the "greater than" or the "less than" subtree of        // this node has to be 2 levels deeper (or else it wouldn't        // need balancing).        if (get_bf(bal_h) > 0) {            // "Greater than" subtree is deeper.            deep_h = get_gt(bal_h);            if (get_bf(deep_h) < 0) {                handle old_h = bal_h;                bal_h = get_lt(deep_h);                set_gt(old_h, get_lt(bal_h));                set_lt(deep_h, get_gt(bal_h));                set_lt(bal_h, old_h);                set_gt(bal_h, deep_h);                int bf = get_bf(bal_h);                if (bf != 0) {                    if (bf > 0) {                        set_bf(old_h, -1);                        set_bf(deep_h, 0);                    } else {                        set_bf(deep_h, 1);                        set_bf(old_h, 0);                    }                    set_bf(bal_h, 0);                } else {                    set_bf(old_h, 0);                    set_bf(deep_h, 0);                }            } else {                set_gt(bal_h, get_lt(deep_h));                set_lt(deep_h, bal_h);                if (get_bf(deep_h) == 0) {                    set_bf(deep_h, -1);                    set_bf(bal_h, 1);                } else {                    set_bf(deep_h, 0);                    set_bf(bal_h, 0);                }                bal_h = deep_h;            }        } else {            // "Less than" subtree is deeper.            deep_h = get_lt(bal_h);            if (get_bf(deep_h) > 0) {                handle old_h = bal_h;                bal_h = get_gt(deep_h);                set_lt(old_h, get_gt(bal_h));                set_gt(deep_h, get_lt(bal_h));                set_gt(bal_h, old_h);                set_lt(bal_h, deep_h);                int bf = get_bf(bal_h);                if (bf != 0) {                    if (bf < 0) {                        set_bf(old_h, 1);                        set_bf(deep_h, 0);                    } else {                        set_bf(deep_h, -1);                        set_bf(old_h, 0);                    }                    set_bf(bal_h, 0);                } else {                    set_bf(old_h, 0);                    set_bf(deep_h, 0);                }            } else {                set_lt(bal_h, get_gt(deep_h));                set_gt(deep_h, bal_h);                if (get_bf(deep_h) == 0) {                    set_bf(deep_h, 1);                    set_bf(bal_h, -1);                } else {                    set_bf(deep_h, 0);                    set_bf(bal_h, 0);                }                bal_h = deep_h;            }        }        return bal_h;    }};template <class Abstractor, unsigned maxDepth, class BSet>inline typename AVLTree<Abstractor, maxDepth, BSet>::handleAVLTree<Abstractor, maxDepth, BSet>::insert(handle h){    set_lt(h, null());    set_gt(h, null());    set_bf(h, 0);    if (abs.root == null())        abs.root = h;    else {        // Last unbalanced node encountered in search for insertion point.        handle unbal = null();        // Parent of last unbalanced node.        handle parent_unbal = null();        // Balance factor of last unbalanced node.        int unbal_bf;        // Zero-based depth in tree.        unsigned depth = 0, unbal_depth = 0;        // 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;        handle hh = abs.root;        handle parent = null();        int cmp;        do {            if (get_bf(hh) != 0) {                unbal = hh;                parent_unbal = parent;                unbal_depth = depth;            }            cmp = cmp_n_n(h, hh);            if (cmp == 0)                // Duplicate key.                return hh;            parent = hh;            hh = cmp < 0 ? get_lt(hh) : get_gt(hh);            branch[depth++] = cmp > 0;        } while (hh != null());        //  Add node to insert as leaf of tree.        if (cmp < 0)            set_lt(parent, h);        else            set_gt(parent, h);        depth = unbal_depth;        if (unbal == null())            hh = abs.root;        else {            cmp = branch[depth++] ? 1 : -1;            unbal_bf = get_bf(unbal);            if (cmp < 0)                unbal_bf--;            else  // cmp > 0                unbal_bf++;            hh = cmp < 0 ? get_lt(unbal) : get_gt(unbal);            if ((unbal_bf != -2) && (unbal_bf != 2)) {                // No rebalancing of tree is necessary.                set_bf(unbal, unbal_bf);                unbal = null();            }        }        if (hh != null())            while (h != hh) {                cmp = branch[depth++] ? 1 : -1;                if (cmp < 0) {                    set_bf(hh, -1);                    hh = get_lt(hh);                } else { // cmp > 0                    set_bf(hh, 1);                    hh = get_gt(hh);                }            }        if (unbal != null()) {            unbal = balance(unbal);            if (parent_unbal == null())                abs.root = unbal;            else {                depth = unbal_depth - 1;                cmp = branch[depth] ? 1 : -1;                if (cmp < 0)                    set_lt(parent_unbal, unbal);                else  // cmp > 0                    set_gt(parent_unbal, unbal);            }        }    }    return h;}template <class Abstractor, unsigned maxDepth, class BSet>inline typename AVLTree<Abstractor, maxDepth, BSet>::handleAVLTree<Abstractor, maxDepth, BSet>::search(key k, typename AVLTree<Abstractor, maxDepth, BSet>::SearchType st){    const int MASK_HIGH_BIT = (int) ~ ((~ (unsigned) 0) >> 1);    int cmp, target_cmp;    handle match_h = null();    handle h = abs.root;    if (st & LESS)        target_cmp = 1;    else if (st & GREATER)        target_cmp = -1;    else        target_cmp = 0;    while (h != null()) {        cmp = cmp_k_n(k, h);        if (cmp == 0) {            if (st & EQUAL) {                match_h = h;                break;            }            cmp = -target_cmp;        } else if (target_cmp != 0)            if (!((cmp ^ target_cmp) & MASK_HIGH_BIT))                // cmp and target_cmp are both positive or both negative.                match_h = h;        h = cmp < 0 ? get_lt(h) : get_gt(h);    }    return match_h;}template <class Abstractor, unsigned maxDepth, class BSet>inline typename AVLTree<Abstractor, maxDepth, BSet>::handleAVLTree<Abstractor, maxDepth, BSet>::search_least(){    handle h = abs.root, parent = null();    while (h != null()) {        parent = h;        h = get_lt(h);    }    return parent;}template <class Abstractor, unsigned maxDepth, class BSet>inline typename AVLTree<Abstractor, maxDepth, BSet>::handleAVLTree<Abstractor, maxDepth, BSet>::search_greatest(){    handle h = abs.root, parent = null();    while (h != null()) {        parent = h;        h = get_gt(h);    }    return parent;}template <class Abstractor, unsigned maxDepth, class BSet>inline typename AVLTree<Abstractor, maxDepth, BSet>::handleAVLTree<Abstractor, maxDepth, BSet>::remove(key k){    // Zero-based depth in tree.    unsigned depth = 0, rm_depth;    // 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;    handle h = abs.root;    handle parent = null(), child;    int cmp, cmp_shortened_sub_with_path;    for (;;) {        if (h == null())            // No node in tree with given key.            return null();        cmp = cmp_k_n(k, h);        if (cmp == 0)            // Found node to remove.            break;        parent = h;        h = cmp < 0 ? get_lt(h) : get_gt(h);        branch[depth++] = cmp > 0;        cmp_shortened_sub_with_path = cmp;    }    handle rm = h;    handle parent_rm = parent;    rm_depth = depth;    // If the node to remove is not a leaf node, we need to get a    // leaf node, or a node with a single leaf as its child, to put    // in the place of the node to remove.  We will get the greatest    // node in the less subtree (of the node to remove), or the least    // node in the greater subtree.  We take the leaf node from the    // deeper subtree, if there is one.    if (get_bf(h) < 0) {        child = get_lt(h);        branch[depth] = false;        cmp = -1;    } else {        child = get_gt(h);        branch[depth] = true;        cmp = 1;    }    depth++;    if (child != null()) {        cmp = -cmp;        do {            parent = h;            h = child;            if (cmp < 0) {                child = get_lt(h);                branch[depth] = false;            } else {                child = get_gt(h);                branch[depth] = true;            }            depth++;        } while (child != null());        if (parent == rm)            // Only went through do loop once.  Deleted node will be replaced            // in the tree structure by one of its immediate children.            cmp_shortened_sub_with_path = -cmp;        else            cmp_shortened_sub_with_path = cmp;        // Get the handle of the opposite child, which may not be null.        child = cmp > 0 ? get_lt(h) : get_gt(h);    }    if (parent == null())        // There were only 1 or 2 nodes in this tree.        abs.root = child;    else if (cmp_shortened_sub_with_path < 0)        set_lt(parent, child);    else        set_gt(parent, child);    // "path" is the parent of the subtree being eliminated or reduced    // from a depth of 2 to 1.  If "path" is the node to be removed, we    // set path to the node we're about to poke into the position of the    // node to be removed.    handle path = parent == rm ? h : parent;    if (h != rm) {        // Poke in the replacement for the node to be removed.        set_lt(h, get_lt(rm));        set_gt(h, get_gt(rm));        set_bf(h, get_bf(rm));        if (parent_rm == null())            abs.root = h;        else {            depth = rm_depth - 1;            if (branch[depth])                set_gt(parent_rm, h);            else                set_lt(parent_rm, h);        }    }    if (path != null()) {        // Create a temporary linked list from the parent of the path node        // to the root node.        h = abs.root;        parent = null();        depth = 0;        while (h != path) {            if (branch[depth++]) {                child = get_gt(h);                set_gt(h, parent);            } else {                child = get_lt(h);                set_lt(h, parent);            }            parent = h;            h = child;        }        // Climb from the path node to the root node using the linked        // list, restoring the tree structure and rebalancing as necessary.        bool reduced_depth = true;        int bf;        cmp = cmp_shortened_sub_with_path;        for (;;) {            if (reduced_depth) {                bf = get_bf(h);                if (cmp < 0)                    bf++;                else  // cmp > 0                    bf--;                if ((bf == -2) || (bf == 2)) {                    h = balance(h);                    bf = get_bf(h);                } else                    set_bf(h, bf);                reduced_depth = (bf == 0);            }            if (parent == null())                break;            child = h;            h = parent;            cmp = branch[--depth] ? 1 : -1;            if (cmp < 0)    {                parent = get_lt(h);                set_lt(h, child);            } else {                parent = get_gt(h);                set_gt(h, child);            }        }        abs.root = h;    }    return rm;}template <class Abstractor, unsigned maxDepth, class BSet>inline typename AVLTree<Abstractor, maxDepth, BSet>::handleAVLTree<Abstractor, maxDepth, BSet>::subst(handle new_node){    handle h = abs.root;    handle parent = null();    int cmp, last_cmp;    /* Search for node already in tree with same key. */    for (;;) {        if (h == null())            /* No node in tree with same key as new node. */            return null();        cmp = cmp_n_n(new_node, h);        if (cmp == 0)            /* Found the node to substitute new one for. */            break;        last_cmp = cmp;        parent = h;        h = cmp < 0 ? get_lt(h) : get_gt(h);    }    /* Copy tree housekeeping fields from node in tree to new node. */    set_lt(new_node, get_lt(h));    set_gt(new_node, get_gt(h));    set_bf(new_node, get_bf(h));    if (parent == null())        /* New node is also new root. */        abs.root = new_node;    else {        /* Make parent point to new node. */        if (last_cmp < 0)            set_lt(parent, new_node);        else            set_gt(parent, new_node);    }    return h;}}#endif

⌨️ 快捷键说明

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