Left-biased tree study notes

Leftist Tree is a parallelizable heap implementation. A left-biased tree is a binary tree whose nodes have the same left and right subtree pointers (left, right) as the nodes of the binary tree, and two attributes, key and distance (dist).

Key value: is the size used to compare nodes.

Distance: Node i is called an external node if and only if the left subtree or right subtree of node i is empty ( left(i) = NULL or right(i) = NULL ); node i is called external node (external node) if and only if the left or right subtree of node i is empty ( left(i) = NULL or right(i) = NULL ); in particular, if node i is itself an external node, then Its distance is 0; while the distance of an empty node is specified as -1 (dist(NULL) = -1).

//The above is from the paper of Huangyuanhe Shenben 2005 National Training Team%%%

Mergeable Heap is also an abstract data type . In addition to supporting the three basic operations of the priority queue (Insert, Minimum, Delete-Min), it also supports an additional operation - the merge operation;

 

Partially taken from:  

basic nature

[Property 1] The key value of a node is less than or equal to the key value of its left and right child nodes.

That is, key(i)≤key(parent(i)) This property is also called heap property. A tree that conforms to this property is Heap-Ordered. With property 1, we can know that the root node of the left-biased tree is the smallest node of the whole tree, so we can complete the operation of taking the smallest node in O(1) time.

[Properties 2] The distance of the left child node of a node is not less than the distance of the right child node.

That is, dist(left(i))≥dist(right(i)) This property is called left-biased property. Property 2 is so that we can maintain the heap property after the other two basic operations of the priority queue (insert node, delete the smallest node) at a lower cost. We'll see it in action later.

These two properties are for each node, so it can be simply concluded that the left and right subtrees of the left-biased tree are all left-biased trees.

From these two properties, we can draw the definition of a left-biased tree: a left-biased tree is a heap-ordered binary tree with a left-biased property.

We know that a node must go through its children to reach the outer node. Due to property 2, the distance of a node is actually the number of edges that the node travels along its right side to an outer node, that is, we have

[Properties 3] The distance of a node is equal to the distance of its right child node plus 1.

That is, dist( i ) = dist( right( i ) ) + 1 The distance of the outer node is 0. Due to property 2, its right child node must be an empty node. In order to satisfy property 3, the distance of empty nodes is specified as -1.

In our impression, balanced trees have very small depths, which means that the number of edges to reach any node is very small. Left-biased trees are not designed for fast access to all nodes, but for fast access to minimal nodes and fast restoration of heap properties after tree modifications. From the figure we can see that it is not balanced. Due to property 2, its structure is skewed to the left, but the concept of distance is not the same as the depth of the tree. A left-biased tree does not mean the number of nodes in the left subtree or is the depth must be greater than the right subtree.

//The above is from Baidu Encyclopedia

 

The left and right subtrees of the left-biased tree are all left-biased trees;

In our impression, balanced trees have very small depths, which means that the number of edges to reach any node is very small. Left-biased trees are not designed for fast access to all nodes, but for fast access to minimal nodes and fast restoration of heap properties after tree modifications.

 

Merge( ) merges the two left-biased trees A and B, and returns a new left-biased tree C that contains all the elements in A and B. In this paper, a left-biased tree is represented by a pointer to its root node.

In a merge operation, the simplest case is when one of the trees is empty (that is, the tree root node pointer is NULL). At this point we just need to return another tree.

If both A and B are not empty, we assume that the root node of A is less than or equal to the root node of B (otherwise swap A, B), use the root node of A as the root node of the new tree C, and the rest is to merge the right of A The subtree is right(A) and B is up.

After merging right(A) and B, the distance of right(A) may become larger, when the distance of right(A) is greater than that of left(A), just exchange right(A) with left(A);

 

Inserting a node: directly treat it as inserting two left-biased trees;

Delete the smallest (largest) value, delete the root node directly, then Merge(left, right);

The rest of the operation is a bit troublesome to update later!

Leave the template:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 100010

int n, m;

int ch[maxn][2], val[maxn], dis[maxn], fa[maxn];

int Merge(int x, int y)
{
    if(x * y == 0) return x + y;
    if(val[x] > val[y] || (val[x] == val[y] && x > y)) swap(x, y);
    ch[x][ 1 ] = Merge(ch[x][ 1 ], y);
    fa[ch[x][1]] = x;
    if(dis[ch[x][0]] < dis[ch[x][1]]) swap(ch[x][0], ch[x][1]);
    dis[x] = dis[ch[x][1]] + 1;
    return x;
}

int getf(int x)
{
    while(fa[x]) x = fa[x];
    return x;
}

void del(int x)
{
    val[x] = -1;
    fa [ch [x] [ 0 ]] = fa [ch [x] [ 1 ]] = 0 ;
    Merge(ch[x][0], ch[x][1]);
}

intmain ()
{
    cin >> n >> m;
    
    dis[0] = -1;
    
    for(register int i = 1 ; i <= n ; i ++) scanf("%d", &val[i]);
    
    while(m--)
    {
        int opt;
        scanf("%d", &opt);
        int x, y; 
        if(opt == 1)
        {
            scanf("%d%d", &x, &y);
            if(val[x] == -1 || val[y] == -1) continue;
            
            if(x == y) continue;
            
            Merge(getf(x), getf(y));
        }
        else if(opt == 2)
        {
            scanf("%d", &x);
            if(val[x] == -1) 
            {
                printf("-1\n");
                continue;
            }
            int fx = getf(x);
            printf("%d\n", val[fx]);
            del(fx);
        }
    }
    return 0;
    
}
zZhBr

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325044619&siteId=291194637
Recommended