/// <summary> /// used to swap the values between 2 node /// </summary> /// <param name="X">node 1</param> /// <param name="Y">node 2</param> public void swap(ref HeapNode X, ref HeapNode Y) // -> O(1) { HeapNode temp = X; // -> O(1) X = Y; // -> O(1) Y = temp; // -> O(1) }
public void swap(int a, int b) { HeapNode temp = mH[a]; mH[a] = mH[b]; mH[b] = temp; }
private void Swape(int index1, int index2) { HeapNode node = NodeList[index1]; NodeList[index1] = NodeList[index2]; NodeList[index2] = node; }
public virtual void bubbleUp(int pos) { int parentIdx = pos / 2; int currentIdx = pos; while (currentIdx > 0 && mH[parentIdx].key > mH[currentIdx].key) { HeapNode currentNode = mH[currentIdx]; HeapNode parentNode = mH[parentIdx]; //swap the positions indexes[currentNode.vertex] = parentIdx; indexes[parentNode.vertex] = currentIdx; swap(currentIdx, parentIdx); currentIdx = parentIdx; parentIdx = parentIdx / 2; } }
public void Insert(int v, double c) { HeapNode neww = new HeapNode(); neww.cost = c; neww.key = v; neww.degree = 0; neww.parent = null; neww.child = null; neww.left = neww; neww.right = neww; neww.can = false; neww.mark = false; pos[v] = neww; if (head != null) { neww.left = head; neww.right = head.right; head.right = neww; neww.right.left = neww; pos[v] = neww; if (neww.cost < head.cost) { head = neww; } } else { head = neww; } sz++; }
public MinHeap(RGBPixel[] G) { this.capacity = G.Length; mH = new HeapNode[capacity + 1]; mH[0] = new HeapNode(); mH[0].key = double.MinValue; indexes = new int[G.Length]; Size = 0; }
public static void decreaseKey(MinHeap minHeap, double newKey, int vertex) { int index = minHeap.indexes[vertex]; HeapNode node = minHeap.mH[index]; node.key = newKey; minHeap.bubbleUp(index); }
public void insert(HeapNode x) { Size++; int idx = Size; mH[idx] = x; indexes[x.vertex] = idx; bubbleUp(idx); }
public bool mark; // -> O(1) /// <summary> /// constractor used to intialize the node /// </summary> /// <param name="key">unique number refers to node</param> /// <param name="value">the value of node </param> public HeapNode(int key, double value) // -> O(1) { this.key = key; // -> O(1) this.weight = value; // -> O(1) this.degree = 0; // -> O(1) this.parent = null; // -> O(1) this.child = null; // -> O(1) this.left = this; // -> O(1) this.right = this; // -> O(1) this.mark = false; // -> O(1) }
public virtual void insert(HeapNode x) { currentSize++; int idx = currentSize; mH[idx] = x; indexes[x.vertex] = idx; bubbleUp(idx); }
public HeapNode extractMin() { HeapNode min = mH[1]; HeapNode lastNode = mH[Size]; indexes[lastNode.vertex] = 1; mH[1] = lastNode; mH[Size] = null; sinkDown(1); Size--; return(min); }
public HeapNode ExtractMinNode() { HeapNode min = NodeList[0]; NodeList[0] = NodeList[NodeList.Count - 1]; NodeList.RemoveAt(NodeList.Count - 1); if (NodeList.Count > 0) { HeapfiyDown(0); } return(min); }
/// <summary> /// Finding the minimum spanning tree in the /// quantization process in which we need to find the minimum costs /// between the colors to be able to group them after that. /// <returns>min cost of MST</returns> /// </summary> public static double MinimumSpanningTree() // [O(V) * O(E *Log V)] ->> O(E Log V) { edges.Clear(); parent = new int[Distinct_Colors_List.Count]; // -> O(1) weight = new double[Distinct_Colors_List.Count]; // -> O(1) visitedHeap = new bool[Distinct_Colors_List.Count]; // -> O(1) FibbonacciHeap heap = new FibbonacciHeap(Distinct_Colors_List.Count); // -> O(1) parent[0] = 0; // -> O(1) weight[0] = 0; // -> O(1) heap.Insert(new HeapNode(0, 0)); // -> O(1) for (int i = 1; i < Distinct_Colors_List.Count; i++) // -> O(V) { parent[i] = -1; // -> O(1) weight[i] = 1e9; // -> O(1) heap.Insert(new HeapNode(i, weight[i])); // -> O(1) } while (heap.size != 0) // [O(E) * O(Log V)] ->> O(E Log V) { HeapNode extractedHeap = heap.Extract_min(); // -> O(Log V) visitedHeap[extractedHeap.key] = true; // -> O(1) for (int i = 0; i < Distinct_Colors_List.Count; i++) // -> O(Log E) * O(1) { if (visitedHeap[i] || i == extractedHeap.key) // -> O(1) { continue; } double R = 0, G = 0, B = 0; // -> O(1) R = Distinct_Colors_List[extractedHeap.key].red - Distinct_Colors_List[i].red; // -> O(1) G = Distinct_Colors_List[extractedHeap.key].green - Distinct_Colors_List[i].green; // -> O(1) B = Distinct_Colors_List[extractedHeap.key].blue - Distinct_Colors_List[i].blue; // -> O(1) double distance = R * R + G * G + B * B; // -> O(1) distance = Math.Sqrt(distance); // -> O(1) if (distance < weight[i]) // -> O(1) { parent[i] = extractedHeap.key; // -> O(1) weight[i] = distance; // -> O(1) heap.decrease_key(i, distance); // -> O(1) } } } double MSTsum = 0; for (int i = 0; i < Distinct_Colors_List.Count; i++) // -> O(V) { MSTsum += weight[i]; // -> O(1) edges.Add(new Edge(i, parent[i], weight[i])); // -> O(1) } return(MSTsum); // -> O(1) }
public virtual void decreaseKey(MinHeap minHeap, double newKey, int vertex) { //get the index which key's needs a decrease; int index = minHeap.indexes[vertex]; //get the node and update its value HeapNode node = minHeap.mH[index]; node.key = newKey; minHeap.bubbleUp(index); }
internal int[] indexes; //will be used to decrease the key public MinHeap(int capacity) { this.capacity = capacity; mH = new HeapNode[capacity + 1]; indexes = new int[capacity]; mH[0] = new HeapNode(); mH[0].key = int.MinValue; mH[0].vertex = -1; currentSize = 0; }
public void Cascase_cut(HeapNode y) { HeapNode z = y.parent; if (z != null) { if (y.mark == false) { y.mark = true; } else { Cut(y, z); Cascase_cut(z); } } }
/// <summary> /// used to change th all parent node in levels (used in decrease_key()) /// </summary> /// <param name="node"></param> public void Cascase_cut(HeapNode node) // -> O(Log V) { HeapNode parent = node.parent; // -> O(1) if (parent != null) // -> O(1) { if (node.mark == false) // -> O(1) { node.mark = true; // -> O(1) } else { Cut(node, parent); // -> O(1) Cascase_cut(parent); // -> O(Log Node(V)) } } }
public void decrease_key(int v, double c) { HeapNode y; HeapNode ptr = pos[v]; ptr.cost = c; y = ptr.parent; if (y != null && ptr.cost < y.cost) { Cut(ptr, y); Cascase_cut(y); } if (ptr.cost < head.cost) { head = ptr; } }
/// <summary> /// decrease node from tree /// </summary> /// <param name="indx">the key of node</param> /// <param name="value">the value of node</param> public void decrease_key(int indx, double value) // -> O(1) { HeapNode updatednode = HeapList[indx]; // -> O(1) updatednode.weight = value; // -> O(1) HeapNode parent = updatednode.parent; // -> O(1) if (parent != null && updatednode.weight < parent.weight) // -> O(1) { Cut(updatednode, parent); // -> O(1) Cascase_cut(parent); // -> O(d) ->> O(1) // Rule: -->> phase(Heap) = tree(Heap)"#roots" + 2 * Root(Max Marked Node). } if (updatednode.weight < minHeap.weight) // -> O(1) { minHeap = updatednode; // -> O(1) } }
/// <summary> /// function used in decrease_key() to change the values of node /// </summary> /// <param name="node">the current node</param> /// <param name="parent">the parent of node</param> public void Cut(HeapNode node, HeapNode parent) // -> O(1) { (node.left).right = node.right; // -> O(1) (node.right).left = node.left; // -> O(1) parent.degree--; // -> O(1) if (node == parent.child) // -> O(1) { parent.child = node.right; // -> O(1) } if (parent.degree == 0) // -> O(1) { parent.child = null; // -> O(1) } node.left = minHeap; // -> O(1) node.right = minHeap.right; // -> O(1) minHeap.right = node; // -> O(1) node.right.left = node; // -> O(1) node.parent = null; // -> O(1) node.mark = false; // -> O(1) }
/// <summary> /// insert new node into tree /// </summary> /// <param name="NewNode">the new node </param> public void Insert(HeapNode NewNode) // -> O(1) { if (minHeap != null) // -> O(1) { NewNode.left = minHeap; // -> O(1) NewNode.right = minHeap.right; // -> O(1) minHeap.right = NewNode; // -> O(1) NewNode.right.left = NewNode; // -> O(1) if (NewNode.weight < minHeap.weight) // -> O(1) { minHeap = NewNode; // -> O(1) } } else { minHeap = NewNode; // -> O(1) } HeapList[NewNode.key] = NewNode; // -> O(1) size++; // -> O(1) }
public void Cut(HeapNode x, HeapNode y) { (x.left).right = x.right; (x.right).left = x.left; y.degree--; if (x == y.child) { y.child = x.right; } if (y.degree == 0) { y.child = null; } x.left = head; x.right = head.right; head.right = x; x.right.left = x; x.parent = null; x.mark = false; }
public virtual HeapNode extractMin() { HeapNode min = mH[1]; HeapNode lastNode = mH[currentSize]; // update the indexes[] and move the last node to the top indexes[lastNode.vertex] = 1; mH[1] = lastNode; mH[currentSize] = null; sinkDown(1); currentSize--; return(min); }
/// <summary> /// to merge trees /// </summary> /// <param name="max">max node</param> /// <param name="min">min node</param> public void mergeTrees(HeapNode max, HeapNode min) // -> O(1) { max.left.right = max.right; // -> O(1) max.right.left = max.left; // -> O(1) max.parent = min; // -> O(1) if (min.child == null) // -> O(1) { min.child = max; // -> O(1) max.right = max; // -> O(1) max.left = max; // -> O(1) } else { max.left = min.child; // -> O(1) max.right = min.child.right; // -> O(1) min.child.right = max; // -> O(1) max.right.left = max; // -> O(1) } min.degree++; // -> O(1) max.mark = false; // -> O(1) }
public HeapNode Extract_min() { HeapNode ptr = head; if (ptr != null) { int kids = ptr.degree; HeapNode oldchild = ptr.child; while (kids > 0) { HeapNode tmp = oldchild.right; oldchild.left.right = oldchild.right; oldchild.right.left = oldchild.left; oldchild.left = head; oldchild.right = head.right; head.right = oldchild; oldchild.right.left = oldchild; oldchild.parent = null; oldchild = tmp; kids--; } } ptr.left.right = ptr.right; ptr.right.left = ptr.left; if (ptr == ptr.right) { head = null; } else { head = ptr.right; Consolidate(); } sz--; return(ptr); }
public void fibb_link(HeapNode y, HeapNode z) { y.left.right = y.right; y.right.left = y.left; y.parent = z; if (z.child == null) { z.child = y; y.right = y; y.left = y; } else { y.left = z.child; y.right = z.child.right; z.child.right = y; y.right.left = y; } z.degree++; y.mark = false; }
/// <summary> /// extract the min node from tree /// </summary> /// <returns>min node</returns> public HeapNode Extract_min() // O(log V + d) ->> O(Log V) { HeapNode min = minHeap; // -> O(1) if (min != null) // -> O(1) { int childs = min.degree; // -> O(1) HeapNode min_child = min.child; // -> O(1) while (childs > 0) // - >> O(degree) { HeapNode tmp = min_child.right; // -> O(1) min_child.left.right = min_child.right; // -> O(1) min_child.right.left = min_child.left; // -> O(1) min_child.left = minHeap; // -> O(1) min_child.right = minHeap.right; // -> O(1) minHeap.right = min_child; // -> O(1) min_child.right.left = min_child; // -> O(1) min_child.parent = null; // -> O(1) min_child = tmp; // -> O(1) childs--; // -> O(1) } } min.left.right = min.right; // -> O(1) min.right.left = min.left; // -> O(1) if (min == min.right) // -> O(1) { minHeap = null; // -> O(1) } else { minHeap = min.right; // -> O(1) Consolidate(); // O(log V + d) ->> O(Log V) } size--; // -> O(1) return(min); // -> O(1) }
public virtual void sinkDown(int k) { int smallest = k; int leftChildIdx = 2 * k; int rightChildIdx = 2 * k + 1; if (leftChildIdx < heapSize() && mH[smallest].key > mH[leftChildIdx].key) { smallest = leftChildIdx; } if (rightChildIdx < heapSize() && mH[smallest].key > mH[rightChildIdx].key) { smallest = rightChildIdx; } if (smallest != k) { HeapNode smallestNode = mH[smallest]; HeapNode kNode = mH[k]; //swap the positions indexes[smallestNode.vertex] = k; indexes[kNode.vertex] = smallest; swap(k, smallest); sinkDown(smallest); } }
public void AddNode(HeapNode node) { NodeList.Add(node); HeapfiyUp(NodeList.Count - 1); }
public virtual void primMST(int[] parent, double[] min_weights, int vertices, RGBPixel[] Nodes) { bool[] inHeap = new bool[vertices]; double[] key = new double[vertices]; //create heapNode for all the vertices HeapNode[] heapNodes = new HeapNode[vertices]; for (int i = 0; i < vertices; i++) { heapNodes[i] = new HeapNode(); //heapnode contains(vertex,key) heapNodes[i].vertex = i; heapNodes[i].key = int.MaxValue; parent[i] = int.MaxValue; min_weights[i] = double.MaxValue; inHeap[i] = true; key[i] = int.MaxValue; } //decrease the key for the first index heapNodes[0].key = 0; //add all the vertices to the MinHeap MinHeap minHeap = new MinHeap(vertices); //add all the vertices to priority queue for (int i = 0; i < vertices; i++) { minHeap.insert(heapNodes[i]); } //while minHeap is not empty parent[0] = -1; min_weights[0] = 0; while (!minHeap.Empty) { //extract the min HeapNode extractedNode = minHeap.extractMin(); //extracted vertex int extractedVertex = extractedNode.vertex; inHeap[extractedVertex] = false; //false because it has been extracted. //iterate through all the adjacent vertices //LinkedList<Edge> list = adjacencylist[extractedVertex]; double weght; for (int l = 0; l < vertices; l++) { weght = ((Nodes[extractedVertex].red - Nodes[l].red) * (Nodes[extractedVertex].red - Nodes[l].red)) + ((Nodes[extractedVertex].blue - Nodes[l].blue) * (Nodes[extractedVertex].blue - Nodes[l].blue)) + ((Nodes[extractedVertex].green - Nodes[l].green) * (Nodes[extractedVertex].green - Nodes[l].green)); //graph.addEdge(j, l, weght); if (inHeap[l]) { int destination = l; double newKey = weght; //check if updated key < existing key, if yes, update if if (key[destination] > newKey) { decreaseKey(minHeap, newKey, destination); //update the parent node for destination parent[destination] = extractedVertex; min_weights[destination] = Math.Sqrt(newKey); key[destination] = newKey; //destination vertex carries the weight between it and its source u in old code } } } //Edge edge = i; //only if edge destination is present in heap } Globals.sum = 0; for (int j = 0; j < vertices; j++) //calculates the sum of the MST { Globals.sum += min_weights[j]; } Globals.sum = Math.Round(Globals.sum, 2); }