Ejemplo n.º 1
0
        private void Exchange(FibonacciHeapNode <K, V> x, FibonacciHeapNode <K, V> y)
        {
            FibonacciHeapNode <K, V> temp = y;

            y = x;
            x = temp;
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     union
        ///     It runs at O(1)
        /// </summary>
        /// <param name="h1"></param>
        /// <param name="h2"></param>
        /// <returns></returns>
        public static MinFibonacciHeap <K, V> Union(MinFibonacciHeap <K, V> h1, MinFibonacciHeap <K, V> h2)
        {
            if (h1 == null || h1.minRoot == null)
            {
                return(h2);
            }
            if (h2 == null || h2.minRoot == null)
            {
                return(h1);
            }

            var heap = new MinFibonacciHeap <K, V>();

            heap.minRoot = h1.minRoot;
            if (h1.minRoot.Key.CompareTo(h2.minRoot.Key) > 0)
            {
                heap.minRoot = h2.minRoot;
            }

            //concatenate the root list of H1 and H2
            FibonacciHeapNode <K, V> h1Node = h1.minRoot.RightSibling;
            FibonacciHeapNode <K, V> h2Node = h2.minRoot.RightSibling;

            h1.minRoot.RightSibling = h2Node;
            h2Node.LeftSibling      = h1.minRoot;
            h2.minRoot.RightSibling = h1Node;
            h1Node.LeftSibling      = h2.minRoot;

            heap.Count = h1.Count + h2.Count;
            return(heap);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     union
        /// </summary>
        /// <param name="heap"></param>
        public void Union(MinFibonacciHeap <K, V> heap)
        {
            MinFibonacciHeap <K, V> h = Union(this, heap);

            Count   = h.Count;
            minRoot = h.minRoot;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// insert it runs at O(1). add a node to the rooted list
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public void Insert(K key, V val)
        {
            Count++;

            var newNode = new FibonacciHeapNode <K, V>(key, val);

            if (maxRoot == null)
            {
                maxRoot             = newNode;
                newNode.LeftSibling = newNode.RightSibling = newNode;
            }
            else
            {
                //insert node to the root list
                FibonacciHeapNode <K, V> temp = maxRoot.RightSibling;
                newNode.RightSibling = temp;
                maxRoot.RightSibling = newNode;
                newNode.LeftSibling  = maxRoot;
                temp.LeftSibling     = newNode;
                if (newNode.Key.CompareTo(maxRoot.Key) > 0)
                {
                    //change the root to biggest one
                    maxRoot = newNode;
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// it runs at O(1) amortized
        /// </summary>
        /// <param name="x"></param>
        /// <param name="newKey"></param>
        public void DecreaseKey(FibonacciHeapNode <K, V> x, K newKey)
        {
            if (newKey.CompareTo(x.Key) > 0)
            {
                throw new Exception("new key is greater than current key");
            }

            if (newKey.CompareTo(x.Key) == 0)
            {
                return;
            }


            x.Key = newKey;
            FibonacciHeapNode <K, V> y = x.Parent;

            if (y != null && x.Key.CompareTo(y.Key) < 0)
            {
                //move x from y to root list
                Cut(x, y);
                CascadingCut(y);
            }

            if (x.Key.CompareTo(minRoot.Key) < 0)
            {
                minRoot = x;
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        ///     union
        /// </summary>
        /// <param name="heap"></param>
        public void Union(MaxFibonacciHeap <K, V> heap)
        {
            MaxFibonacciHeap <K, V> h = Union(this, heap);

            Count   = h.Count;
            maxRoot = h.maxRoot;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// extractMax it runs at O(D(n)) amortized time. D(n) is maximum degree which O(lgn)
        /// the max one are removed from heap
        /// it's where the delayed work of consolidating trees finally occurs
        /// </summary>
        /// <returns></returns>
        public FibonacciHeapNode <K, V> ExtractMax()
        {
            if (maxRoot == null || Count <= 0)
            {
                throw new Exception("Heap is empty");
            }

            //for each child in maxroot add it in the root list
            List <FibonacciHeapNode <K, V> > list = maxRoot.GetChildren();

            maxRoot.Child  = null;
            maxRoot.Degree = 0;
            foreach (var node in list)
            {
                node.Parent = null;
                //insert node to root list
                FibonacciHeapNode <K, V> right = maxRoot.RightSibling;
                node.RightSibling    = right;
                right.LeftSibling    = node;
                maxRoot.RightSibling = node;
                node.LeftSibling     = maxRoot;
            }

            FibonacciHeapNode <K, V> temp  = maxRoot;
            FibonacciHeapNode <K, V> tempR = maxRoot.RightSibling;

            if (temp == tempR)
            {
                //no element in heap
                maxRoot = null;
                Count   = 0;
                return(temp);
            }

            //remove maxroot
            FibonacciHeapNode <K, V> tempL = maxRoot.LeftSibling;

            tempL.RightSibling = tempR;
            tempR.LeftSibling  = tempL;
            //maxRoot may not the max one here
            maxRoot = tempR;
            Consolidate();
            Count--;
            return(temp);
        }
Ejemplo n.º 8
0
        private void CascadingCut(FibonacciHeapNode <K, V> node)
        {
            FibonacciHeapNode <K, V> parent = node.Parent;

            if (parent != null)
            {
                if (node.Mark == false)
                {
                    //cut the first child
                    node.Mark = true;
                }
                else
                {
                    //cut two children from parent
                    Cut(node, parent);
                    CascadingCut(parent);
                }
            }
        }
        public List <FibonacciHeapNode <K, V> > GetChildren()
        {
            List <FibonacciHeapNode <K, V> > list = new List <FibonacciHeapNode <K, V> >();

            if (Child == null)
            {
                return(list);
            }

            FibonacciHeapNode <K, V> temp = Child;

            while (true)
            {
                list.Add(temp);
                temp = temp.RightSibling;
                if (temp == Child)
                {
                    break;
                }
            }
            return(list);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// x.key&lt;=y.key  make y a child of x
        /// </summary>
        /// <param name="y"></param>
        /// <param name="x"></param>
        private void HeapLink(FibonacciHeapNode <K, V> y, FibonacciHeapNode <K, V> x)
        {
            FibonacciHeapNode <K, V> temp = y;
            FibonacciHeapNode <K, V> yL = y.LeftSibling, yR = y.RightSibling;

            yL.RightSibling = yR;
            yR.LeftSibling  = yL;
            y.Parent        = x;
            x.Degree++;
            if (x.Child == null)
            {
                x.Child       = y;
                y.LeftSibling = y.RightSibling = y;
            }
            else
            {
                FibonacciHeapNode <K, V> t = x.Child.RightSibling;
                x.Child.RightSibling = y;
                y.LeftSibling        = x.Child;
                y.RightSibling       = t;
                t.LeftSibling        = y;
            }
            y.Mark = false;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// move x from y to root list
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private void Cut(FibonacciHeapNode <K, V> x, FibonacciHeapNode <K, V> y)
        {
            y.Degree--;

            if (x.LeftSibling == x)
            {
                y.Child = null;
            }
            else
            {
                x.LeftSibling.RightSibling = x.RightSibling;
                x.RightSibling.LeftSibling = x.LeftSibling;
            }

            // add x to the root list
            FibonacciHeapNode <K, V> t = minRoot.RightSibling;

            minRoot.RightSibling = x;
            x.LeftSibling        = minRoot;
            x.RightSibling       = t;
            t.LeftSibling        = x;
            x.Parent             = null;
            x.Mark = false;
        }
Ejemplo n.º 12
0
        /// <summary>
        ///     insert
        ///     it runs at O(1)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public void Insert(K key, V val)
        {
            var node = new FibonacciHeapNode <K, V>(key, val);

            if (minRoot == null)
            {
                minRoot          = node;
                node.LeftSibling = node.RightSibling = node;
            }
            else
            {
                //insert node to root list
                FibonacciHeapNode <K, V> temp = minRoot.RightSibling;
                node.RightSibling    = temp;
                minRoot.RightSibling = node;
                node.LeftSibling     = minRoot;
                temp.LeftSibling     = node;
                if (node.Key.CompareTo(minRoot.Key) < 0)
                {
                    minRoot = node;
                }
            }
            Count++;
        }
Ejemplo n.º 13
0
 /// <summary>
 /// it runs at O(D(n)) amortized time. D(n) is maximum degree, which O(lgn)
 /// </summary>
 /// <param name="node">the node to delete</param>
 /// <param name="min">the min value so that we can decrease the node to the root</param>
 public void Delete(FibonacciHeapNode <K, V> node, K min)
 {
     DecreaseKey(node, min);
     ExtractMin();
 }
Ejemplo n.º 14
0
 /// <summary>
 /// constructor
 /// </summary>
 public MaxFibonacciHeap()
 {
     Count   = 0;
     maxRoot = null;
 }
Ejemplo n.º 15
0
 /// <summary>
 /// it runs at O(D(n)) amortized time. D(n) is maximum degree, which O(lgn)
 /// </summary>
 /// <param name="node">the node to delete</param>
 /// <param name="max">the max value so that we can increase the node to the root</param>
 public void Delete(FibonacciHeapNode <K, V> node, K max)
 {
     IncreaseKey(node, max);
     ExtractMax();
 }
Ejemplo n.º 16
0
 public MinFibonacciHeap()
 {
     Count   = 0;
     minRoot = null;
 }
Ejemplo n.º 17
0
        /// <summary>
        /// consolidate the heap util every node in the root list have different degree value
        /// 1)find two roots x and y in the root list with the same degree. without loss of generality, let x.key &lt;= y.key
        /// 2)remove y from the root list, and make y a child of x by calling the HeapLink procedure. the procedure increments the attribute x.degree and clear the mark on y
        /// </summary>
        private void Consolidate()
        {
            if (minRoot == null)
            {
                return;
            }

            //if arr[i] = y, then y is currently a root with y.degree = i
            var arr = new FibonacciHeapNode <K, V> [MaxDegree() + 1];
            FibonacciHeapNode <K, V> temp = minRoot;
            var rootList = new List <FibonacciHeapNode <K, V> >();

            while (true)
            {
                rootList.Add(temp);
                temp = temp.RightSibling;
                if (temp == minRoot)
                {
                    break;
                }
            }

            foreach (var fnode in rootList)
            {
                FibonacciHeapNode <K, V> x = fnode;
                int d = fnode.Degree;
                while (arr[d] != null)
                {
                    //y must appear before x in the rootList  & x and y have same degree
                    FibonacciHeapNode <K, V> y = arr[d];
                    if (x.Key.CompareTo(y.Key) > 0)
                    {
                        Exchange(x, y);
                    }

                    HeapLink(y, x);
                    arr[d] = null;
                    d++;
                }
                arr[d] = x;
            }

            minRoot = null;
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] != null)
                {
                    if (minRoot == null)
                    {
                        minRoot             = arr[i];
                        minRoot.LeftSibling = minRoot.RightSibling = minRoot;
                    }
                    else
                    {
                        FibonacciHeapNode <K, V> minR = minRoot.RightSibling;
                        minRoot.RightSibling = arr[i];
                        arr[i].LeftSibling   = minRoot;
                        arr[i].RightSibling  = minR;
                        minR.LeftSibling     = arr[i];
                        if (minRoot.Key.CompareTo(arr[i].Key) > 0)
                        {
                            minRoot = arr[i];
                        }
                    }
                }
            }
        }