Beispiel #1
0
        public static node minimum(node1 head)
        {
            node m = head.root;

            for (int i = 0; i < head.height; ++i)
            {
                if (m.child1.key == m.key)
                {
                    m = m.child1;
                }
                else if (m.child2.key == m.key)
                {
                    m = m.child2;
                }
                else if (m.child3.key == m.key)
                {
                    m = m.child3;
                }
                else if (m.child4.key == m.key)
                {
                    m = m.child4;
                }
            }
            return(m);
        }
Beispiel #2
0
 public static void insert(ref node1 h1, node x)
 {
     if (h1.height == -1)
     {
         h1.root   = x;
         h1.height = 0;
     }
     else
     {
         node1 h2 = new node1(0, x);
         h1 = union234(h1, h2);
     }
 }
Beispiel #3
0
        static void Main(string[] args)
        {
            node1 head   = node1.makeHeap();
            node  node_1 = new node(2);

            insert(ref head, node_1);
            for (int i = 0; i < 10; i++)
            {
                node node_2 = new node(i + 3);
                insert(ref head, node_2);
            }
            //remove(head,node_2);
            display(head.root);
            Console.Read();
        }
Beispiel #4
0
 public static void decreaseKey(node1 head, node x, int k)
 {
     if (k > x.key)
     {
         Console.Write("error");
     }
     else
     {
         x.key = k;
         node p = x;
         while (p.parent != null && p.parent.key > k)
         {
             p.parent.key = k;
             p            = p.parent;
         }
     }
 }
Beispiel #5
0
        public static node1 union234(node1 heap1, node1 heap2)
        {
            if (heap1.height == heap2.height)
            {
                node  root = new node(Math.Min(heap1.root.key, heap2.root.key), 2, null, heap1.root, heap2.root);
                node1 head = new node1(heap1.height + 1, root);
                return(head);
            }
            if (heap2.height > heap1.height)
            {
                swap(ref heap1, ref heap2);
            }
            node p = heap1.root;

            if (p.degree == 4)
            {
                node l  = new node(Math.Min(p.child1.key, p.child2.key), 2, null, p.child1, p.child2);
                node r  = new node(Math.Min(p.child3.key, p.child4.key), 2, null, p.child3, p.child4);
                node pr = new node(Math.Min(l.key, r.key), 2, null, l, r);
                l.parent   = pr;
                r.parent   = pr;
                heap1.root = pr;
                heap1.height++;
            }
            p = heap1.root;
            for (int i = 0; i < heap1.height - heap2.height - 1; ++i)
            {
                if (p.degree < 4)
                {
                    if (p.child3 != null && p.child3.degree < 4)
                    {
                        p = p.child3;
                    }
                    else if (p.child2 != null && p.child2.degree < 4)
                    {
                        p = p.child2;
                    }
                    else
                    {
                        p = p.child1;
                    }
                }
                else
                {
                    if (p.parent.child3 == null)
                    {
                        p.parent.child3 = new node(Math.Min(p.child3.key, p.child4.key), 2, p.child3, p.child4);
                        --i;
                    }
                    else
                    {
                        p.parent.child4 = new node(Math.Min(p.child3.key, p.child4.key), 2, p.child3, p.child4);
                        --i;
                    }
                    p.parent.degree++;
                    p.degree -= 2;
                }
            }
            if (p.degree < 4)
            {
                if (p.child3 == null)
                {
                    p.child3        = heap2.root;
                    p.child3.parent = p;
                    p.child3.degree = heap2.root.degree;
                    p.child3.child1 = heap2.root.child1;
                    p.child3.child2 = heap2.root.child2;
                    p.child3.child3 = heap2.root.child3;
                    p.child3.child4 = heap2.root.child4;
                    p.degree++;
                }
                else
                {
                    p.child4        = heap2.root;
                    p.child4.parent = p;
                    p.child4.degree = heap2.root.degree;
                    p.child4.child1 = heap2.root.child1;
                    p.child4.child2 = heap2.root.child2;
                    p.child4.child3 = heap2.root.child3;
                    p.child4.child4 = heap2.root.child4;
                    p.degree++;
                }
            }
            else
            {
                if (p.parent.child3 == null)
                {
                    p.parent.child3 = new node(Math.Min(p.child3.key, p.child4.key), 2, p.child3, p.child4);
                }
                else
                {
                    p.parent.child4 = new node(Math.Min(p.child3.key, p.child4.key), 2, p.child3, p.child4);
                }
                p.parent.degree++;
                p.degree -= 2;
                p.parent.child3.child3 = heap2.root;
                p.parent.child3.child3.degree++;
            }
            p = heap2.root;
            while (p.parent != null)
            {
                if (p.parent.key > p.key)
                {
                    p.parent.key = p.key;
                }
                else
                {
                    break;
                }
            }
            return(heap1);
        }
Beispiel #6
0
 public static void remove(node1 head, ref node x) //deletes a given leaf x
 {
     decreaseKey(head, x, -1);
     extractMin(head);
 }
Beispiel #7
0
        public static node1 makeHeap()
        {
            node1 head = new node1();

            return(head);
        }
Beispiel #8
0
        public static node extractMin(node1 head) //extracts a leaf with the smallest key; returns the node with the smallest key
        {
            node mini = minimum(head);

            if (mini == head.root || mini.parent == null)
            {
                head.root = null;
                head.height--;
                return(null);
            }
            if (mini.parent == head.root && head.root.degree == 2)
            {
                head.root = new node(Math.Max(head.root.child1.key, head.root.child2.key), 0);
                head.height--;
                return(head.root);
            } //simplest cases
            node p = mini;
            node q = p;

            if (mini.parent.degree > 2) //not so complicated case: we can delete it and then aligne
            {
                if (mini == mini.parent.child1)
                {
                    swap(ref mini.parent.child1, ref mini.parent.child2);
                }
                if (mini == mini.parent.child2)
                {
                    swap(ref mini.parent.child2, ref mini.parent.child3);
                }
                if (mini == mini.parent.child3 && mini.parent.child4 != null)
                {
                    swap(ref mini.parent.child3, ref mini.parent.child4);
                }
                mini.parent.degree--;
                if (mini.parent.child4 != null)
                {
                    mini.parent.child4 = null;
                }
                else
                {
                    mini.parent.child3 = null;
                }
            }
            else //its parent has only 2 childs
            {
                p    = mini.parent;
                mini = null;
                if (p.child1 == null)
                {
                    swap(ref p.child1, ref p.child2);
                }
                p.key = p.child1.key;
                p.degree--;
                while (true)              //we can get til the root
                {
                    if (p.parent == null) //it got to the root
                    {
                        q = head.root = p.child1;
                        head.height--;
                        break;
                    }
                    else
                    {
                        if (p.parent.degree > 2)                 //we can fix it with 1 step
                        {
                            if (p.parent.child1.degree != 1)     // we can get him a sibling form here
                            {
                                if (p.parent.child1.degree == 2) // we move the single leaf
                                {
                                    p.parent.child1.child3 = p.child1;
                                    p.parent.child1.degree++;
                                    p.parent.degree--;
                                    p.parent.child1.key = Math.Min(p.parent.child1.key, p.parent.child1.child3.key);
                                    if (p == p.parent.child1) // we gotta align
                                    {
                                        swap(ref p.parent.child1, ref p.parent.child2);
                                    }
                                    if (p == p.parent.child2)
                                    {
                                        swap(ref p.parent.child2, ref p.parent.child3);
                                    }
                                    if (p == p.parent.child3 && p.parent.child4 != null)
                                    {
                                        swap(ref p.parent.child3, ref p.parent.child4);
                                    }
                                    if (p.parent.child4 != null)
                                    {
                                        p.parent.child4 = null;
                                    }
                                    else
                                    {
                                        p.parent.child3 = null;
                                    }
                                    p.parent.key = Math.Min(p.parent.child1.key, p.parent.child2.key); //refreshing the keys
                                    if (p.parent.child3 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.child3.key, p.parent.key);
                                    }
                                }
                                else // we get a sibling for him from his uncle
                                {
                                    if (p.parent.child1.child4 != null)
                                    {
                                        p.child2 = p.parent.child1.child4;
                                        p.parent.child1.child4 = null;
                                        p.parent.child1.degree--;
                                        p.degree++;
                                    }
                                    else
                                    {
                                        p.child2 = p.parent.child1.child3;
                                        p.parent.child1.child3 = null;
                                        p.parent.child1.degree--;
                                        p.degree++;
                                    }
                                    p.parent.child1.key = Math.Min(p.parent.child1.child1.key, p.parent.child1.child2.key); //key refreshing
                                    if (p.parent.child1.child3 != null)
                                    {
                                        p.parent.child1.key = Math.Min(p.parent.child1.key, p.parent.child1.child3.key);
                                    }
                                    if (p.parent.child1.child4 != null)
                                    {
                                        p.parent.child1.key = Math.Min(p.parent.child1.key, p.parent.child1.child4.key);
                                    }
                                    p.key        = Math.Min(p.child1.key, p.child2.key);
                                    p.parent.key = Math.Min(p.parent.child1.key, p.parent.child2.key);
                                    if (p.parent.child3 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.child3.key, p.parent.key);
                                    }
                                    if (p.parent.child4 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.child4.key, p.parent.key);
                                    }
                                }
                            }
                            else if (p.parent.child2.degree != 1) // we can get him a sibling form here
                            {
                                if (p.parent.child2.degree == 2)  // we move teh single leaf
                                {
                                    p.parent.child2.child3 = p.child1;
                                    p.parent.child2.degree++;
                                    p.parent.degree--;
                                    p.parent.child2.key = Math.Min(p.parent.child2.key, p.parent.child2.child3.key);
                                    if (p == p.parent.child1) //aligning
                                    {
                                        swap(ref p.parent.child2, ref p.parent.child2);
                                    }
                                    if (p == p.parent.child2)
                                    {
                                        swap(ref p.parent.child2, ref p.parent.child3);
                                    }
                                    if (p == p.parent.child3 && p.parent.child4 != null)
                                    {
                                        swap(ref p.parent.child3, ref p.parent.child4);
                                    }
                                    if (p.parent.child4 != null)
                                    {
                                        p.parent.child4 = null;
                                    }
                                    else
                                    {
                                        p.parent.child3 = null;
                                    }
                                    p.parent.key = Math.Min(p.parent.child1.key, p.parent.child2.key); //refreshing the keys
                                    if (p.parent.child3 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.child3.key, p.parent.key);
                                    }
                                }
                                else //we get him a siblin gfrom his uncle
                                {
                                    if (p.parent.child2.child4 != null)
                                    {
                                        p.child2 = p.parent.child2.child4;
                                        p.parent.child2.child4 = null;
                                        p.parent.child2.degree--;
                                        p.degree++;
                                    }
                                    else
                                    {
                                        p.child2 = p.parent.child2.child3;
                                        p.parent.child2.child3 = null;
                                        p.parent.child2.degree--;
                                        p.degree++;
                                    }
                                    p.parent.child2.key = Math.Min(p.parent.child2.child1.key, p.parent.child2.child2.key);
                                    if (p.parent.child1.child3 != null)
                                    {
                                        p.parent.child2.key = Math.Min(p.parent.child2.key, p.parent.child2.child3.key);
                                    }
                                    if (p.parent.child2.child4 != null)
                                    {
                                        p.parent.child2.key = Math.Min(p.parent.child2.key, p.parent.child2.child4.key);
                                    }
                                    p.key        = Math.Min(p.child1.key, p.child2.key);
                                    p.parent.key = Math.Min(p.parent.child1.key, p.parent.child2.key);
                                    if (p.parent.child3 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.child3.key, p.parent.key);
                                    }
                                    if (p.parent.child4 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.child4.key, p.parent.key); //keys resfreshed
                                    }
                                }
                            }
                            q = p;
                            break;
                        }
                        else
                        {
                            if (p.parent.child1.degree != 1)
                            {
                                if (p.parent.child1.degree > 2) //getting him a sibling from his uncle
                                {
                                    if (p.parent.child1.child4 != null)
                                    {
                                        p.child2 = p.parent.child1.child4;
                                        p.parent.child1.child4 = null;
                                    }
                                    else
                                    {
                                        p.child2 = p.parent.child1.child3;
                                        p.parent.child1.child3 = null;
                                    }
                                    p.parent.child1.degree--;
                                    p.parent.key = Math.Min(p.parent.child1.key, p.parent.child2.key); //surely refreshing the keys
                                    if (p.parent.child3 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.key, p.parent.child3.key);
                                    }
                                    p.degree++;
                                    q = p;
                                    break;
                                }
                                else // the megaworst case
                                {
                                    p.parent.child1.child3 = p.child1;
                                    p.parent.child1.degree++;
                                    p.parent.degree--;
                                    p.child1     = null;
                                    p            = p.parent;
                                    p.child1.key = Math.Min(p.child1.key, p.child1.child3.key);
                                    p.key        = p.child1.key;
                                    p.child2     = null;
                                }
                            }
                            else if (p.parent.child2.degree != 1)
                            {
                                if (p.parent.child2.degree > 2) //getting him a sibling from his uncle
                                {
                                    if (p.parent.child2.child4 != null)
                                    {
                                        p.child2 = p.parent.child2.child4;
                                        p.parent.child2.child4 = null;
                                    }
                                    else
                                    {
                                        p.child2 = p.parent.child2.child3;
                                        p.parent.child2.child3 = null;
                                    }
                                    p.parent.child2.degree--;
                                    p.parent.key = Math.Min(p.parent.child1.key, p.parent.child2.key); //surely refreshing the keys
                                    if (p.parent.child3 != null)
                                    {
                                        p.parent.key = Math.Min(p.parent.key, p.parent.child3.key);
                                    }
                                    p.degree++;
                                }
                                else // the meagworst case
                                {
                                    p.parent.child2.child3 = p.child1;
                                    p.parent.child2.degree++;
                                    swap(ref p.parent.child2, ref p);
                                    p.parent.degree--;
                                    p.child1 = null;
                                    p        = p.parent;
                                    p.child2 = null;
                                }
                            }
                        }
                    }
                }
            }
            while (q.parent == q.parent) // refreshing the minimum of the whole heap
            {
                q     = q.parent;
                q.key = Math.Min(q.child1.key, q.child2.key);
                if (q.child3 == q.child3)
                {
                    q.key = Math.Min(q.key, q.child3.key);
                }
                if (q.child4 == q.child4)
                {
                    q.key = Math.Min(q.key, q.child4.key);
                }
            }
            return(minimum(head));
        }