Example #1
0
// The main function that builds Huffman tree
struct node* buildHuffmanTree(char data[], int freq[], int size)
{
    struct node *left, *right, *top;
 
    // Step 1: Create a min heap of Limit equal to size.  Initially, there are
    // modes equal to size.
    struct Heap* Heap = createAndBuildHeap(data, freq, size);
 
    // Iterate while size of heap doesn't become 1
    while (!isSizeOne(Heap))
    {
        // Step 2: Extract the two minimum freq items from min heap
        left = extractMin(Heap);
        right = extractMin(Heap);
 
        // Step 3:  Create a new internal node with frequency equal to the
        // sum of the two nodes frequencies. Make the two extracted node as
        // left and right children of this new node. Add this node to the min heap
        // '$' is a special value for internal nodes, not used
        top = newNode('$', left->freq + right->freq);
        top->left = left;
        top->right = right;
        insertHeap(Heap, top);
    }
 
    // Step 4: The remaining node is the root node and the tree is complete.
    return extractMin(Heap);
}
Example #2
0
void HuffmanTree::mergeQueue(){
    while(queue.size() != 1){
        unique_ptr<tree_node> z(new tree_node);
        z->left = extractMin();
        z->right = extractMin();
        z->f = z->left->f + z->right->f;
        queue.push(move(z));
    }
    root = extractMin();
}
MinHeapNode* buildHuffmanTree (char data[], int freq[], int size)
{
	MinHeapNode* left; MinHeapNode* right; MinHeapNode* top;
	MinHeap* minHeap = createAndBuildMinHeap(data,freq,size);
	while (!isSizeOne(minHeap))
	{
		left = extractMin(minHeap);
		right = extractMin(minHeap);
		top = newNode('$', left->freq + right->freq);
		top->left = left;
		top->right = right;
		insertMinHeap(minHeap,top);
	}
	return extractMin(minHeap);
}
Example #4
0
void dijkstra(ALGraph G,int s,int d[],int pi[],int Q[])
{ //Q[]是最小优先队列,Q[1..n]中存放的是图顶点标号,Q[0]中存放堆的大小
 //优先队列中有key的概念,这里key可以从d[]中取得。比如说,Q[2]的大小(key)为 d[ Q[2] ]

 initSingleSource(G,s,d,pi);  //1、初始化结点工作
 
 //2、初始化队列
 Q[0] = G.vexnum;
 int i=1;
 for(;i<=Q[0];i++)

 {
  Q[i] = i-1;
 }
 Q[1] = s;
 Q[s+1] = 0;

 int u;
 int v;
 while(Q[0]!=0)

 {
  buildMinHeap(Q,d);     //3.1、建立最小堆
  u = extractMin(Q,d);   //3.2、从最小队列中,抽取最小结点
  ArcNode* arcNodePt = G.vertices[u].firstarc;
  while(arcNodePt!=NULL)
 {
   v = arcNodePt->adjvex;
   relax(u,v,G,d,pi);    //4、松弛操作。
   arcNodePt = arcNodePt->nextarc;
  }
 }

}
Example #5
0
// The main function that constructs Minimum Spanning Tree (MST)
// using Prim's algorithm
void PrimMST(struct Graph* graph)
{
    int V = graph->V;// Get the number of vertices in graph
    int parent[V];   // Array to store constructed MST
    int key[V];      // Key values used to pick minimum weight edge in cut
 
    // minHeap represents set E
    struct MinHeap* minHeap = createMinHeap(V);
 
    // Initialize min heap with all vertices. Key value of
    // all vertices (except 0th vertex) is initially infinite
    for (int v = 1; v < V; ++v)
    {
        parent[v] = -1;
        key[v] = INT_MAX;
        minHeap->array[v] = newMinHeapNode(v, key[v]);
        minHeap->pos[v] = v;
    }
 
    // Make key value of 0th vertex as 0 so that it
    // is extracted first
    key[0] = 0;
    minHeap->array[0] = newMinHeapNode(0, key[0]);
    minHeap->pos[0]   = 0;
 
    // Initially size of min heap is equal to V
    minHeap->size = V;
 
    // In the followin loop, min heap contains all nodes
    // not yet added to MST.
    while (!isEmpty(minHeap))
    {
        // Extract the vertex with minimum key value
        struct MinHeapNode* minHeapNode = extractMin(minHeap);
        int u = minHeapNode->v; // Store the extracted vertex number
 
        // Traverse through all adjacent vertices of u (the extracted
        // vertex) and update their key values
        struct AdjListNode* pCrawl = graph->array[u].head;
        while (pCrawl != NULL)
        {
            int v = pCrawl->dest;
 
            // If v is not yet included in MST and weight of u-v is
            // less than key value of v, then update key value and
            // parent of v
            if (isInMinHeap(minHeap, v) && pCrawl->weight < key[v])
            {
                key[v] = pCrawl->weight;
                parent[v] = u;
                decreaseKey(minHeap, v, key[v]);
            }
            pCrawl = pCrawl->next;
        }
    }
 
    // print edges of MST
    printArr(parent, V);
}
BinomialHeap *BinomialHeap::deleteNode(BinomialHeap &bh, void* target)
{
    void *minValue=getmin(this->size);
    int b = INT_MIN;
    void *p = &b;
    decreaseKey(bh,target,p); //conseguir el valor minimo de acuerdo al size
    extractMin(bh);
}
Example #7
0
// The main function that calulates distances of shortest paths from src to all
// vertices. It is a O(ELogV) function
void dijkstra(struct Graph* graph, int src)
{
    int V = graph->V;// Get the number of vertices in graph
    int dist[V];      // dist values used to pick minimum weight edge in cut
 
    // minHeap represents set E
    struct MinHeap* minHeap = createMinHeap(V);
 
    // Initialize min heap with all vertices. dist value of all vertices 
    for (int v = 0; v < V; ++v)
    {
        dist[v] = INT_MAX;
        minHeap->array[v] = newMinHeapNode(v, dist[v]);
        minHeap->pos[v] = v;
    }
 
    // Make dist value of src vertex as 0 so that it is extracted first
    minHeap->array[src] = newMinHeapNode(src, dist[src]);
    minHeap->pos[src]   = src;
    dist[src] = 0;
    decreaseKey(minHeap, src, dist[src]);
 
    // Initially size of min heap is equal to V
    minHeap->size = V;
 
    // In the followin loop, min heap contains all nodes
    // whose shortest distance is not yet finalized.
    while (!isEmpty(minHeap))
    {
        // Extract the vertex with minimum distance value
        struct MinHeapNode* minHeapNode = extractMin(minHeap);
        int u = minHeapNode->v; // Store the extracted vertex number
 
        // Traverse through all adjacent vertices of u (the extracted
        // vertex) and update their distance values
        struct AdjListNode* pCrawl = graph->array[u].head;
        while (pCrawl != NULL)
        {
            int v = pCrawl->dest;
 
            // If shortest distance to v is not finalized yet, and distance to v
            // through u is less than its previously calculated distance
            if (isInMinHeap(minHeap, v) && dist[u] != INT_MAX && 
                                          pCrawl->weight + dist[u] < dist[v])
            {
                dist[v] = dist[u] + pCrawl->weight;
 
                // update distance value in min heap also
                decreaseKey(minHeap, v, dist[v]);
            }
            pCrawl = pCrawl->next;
        }
    }
 
    // print the calculated shortest distances
    printArr(dist, V);
}
void printSortedElements ( struct MinHeap * heap ) {

       int i;
       int heap_size = heap -> current_size;
       for ( i = 0; i < heap_size; i++ ) {

            struct MinHeapNode * node = extractMin( heap );
	    printf ( "%d %d \n", node -> element, node -> priority );
       }
}
Example #9
0
int dijkstra(PWDG graph, int src, int dst) {

  int V = graph->count;
  int dist[V];

  // Clone node:
  if (src == dst) {
    wdg_clone(graph, src);
    dst = V; V++;
  }

  pMinHeap minHeap = createMinHeap(V);

  for (int v=0; v<V; ++v) {
    dist[v] = INT_MAX;
    minHeap->array[v] = newMinHeapNode(v, dist[v]);
    minHeap->pos[v] = v;
  }

  dist[src] = 0;
  decreaseKey(minHeap, src, dist[src]);
  minHeap->size = V;

  while (!isEmpty(minHeap)) {

    pMinHeapNode minHeapNode = extractMin(minHeap);
    int u = minHeapNode->v;

    if (u == dst) {
      wdg_unclone(graph);
      return dist[u];
    }

    PNODE pCrawl = graph->list[u].head;

    while (pCrawl != NULL) {

      int v = pCrawl->dst;

      if (isInMinHeap(minHeap, v) && dist[u] != INT_MAX && pCrawl->wgt + dist[u] < dist[v]) {
        dist[v] = dist[u] + pCrawl->wgt;
        decreaseKey(minHeap, v, dist[v]);
      }

      pCrawl = pCrawl->next;
    }
  }

  #ifdef DEBUG
  printArr(dist, V, src);
  #endif

  wdg_unclone(graph);
  return -1;
}
Example #10
0
void testExtractMin() {
    printf("Test 5. extractMin: ");
    MinHeap heap;
    int array[] = {2,3,4,5};
    heap.size = 4;
    for (unsigned int i = 0; i < heap.size; i++) {
        heap.array[i] = array[i];
    }

    int tmp = extractMin(&heap);

    int res1[3] = {3,5,4};
    int res2[2] = {4,5};
    int res3[1] = {5};

    if (!cmpArray(heap.array, res1, 3) || (heap.size != 3) || (tmp != 2)) {
        printf("NOK - chyba ve funkci extractMin\n");
    } else {
        tmp = extractMin(&heap);
        if (!cmpArray(heap.array, res2, 2) || (heap.size != 2) || (tmp != 3)) {
            printf("NOK - chyba ve funkci extractMin\n");
        } else{
            tmp = extractMin(&heap);
            if (!cmpArray(heap.array, res3, 1) || (heap.size != 1) || (tmp != 4)) {
                printf("NOK - chyba ve funkci extractMin\n");
            } else {
                tmp = extractMin(&heap);
                if ((heap.size != 0) || (tmp != 5)) {
                    printf("NOK - chyba ve funkci extractMin\n");
                } else {
                    if (extractMin(&heap) == INT_MAX) {
                        printf("OK\n");
                    } else {
                        printf("NOK - chyba ve funkci extractMin na prazne halde\n");
                    }
                }
            }
        }
    }
    makeGraph(&heap, "extract.dot");
    printf("Vykreslenou haldu najdete v souboru extract.dot\n");
}
Example #11
0
File: FibHeap.cpp Project: cran/CRF
FibHeap::~FibHeap()
{
  FibHeapNode *temp;
  
  if (getHeapOwnership()) {
    while (m_min_root != NULL) {
      temp = extractMin();
      delete temp;
    }
  }
}
Example #12
0
// The main function that builds Huffman tree
struct MinHeapNode* buildHuffmanTree(uint16 freq[])
{
    struct MinHeapNode *left, *right, *top, *ret_node;

    // Step 1: Create a min heap of capacity equal to size.  Initially, there are
    // modes equal to size.
    struct MinHeap* minHeap = createAndBuildMinHeap(freq, HUFFMAN_STEPS);
    if (minHeap == NULL) {
        hError |= (1 << 5);
        return NULL;
    }

    // Iterate while size of heap doesn't become 1
    while (!isSizeOne(minHeap))
    {
        // Step 2: Extract the two minimum freq items from min heap
        left = extractMin(minHeap);
        right = extractMin(minHeap);

        // Step 3:  Create a new internal node with frequency equal to the
        // sum of the two nodes frequencies. Make the two extracted node as
        // left and right children of this new node. Add this node to the min heap
        // '$' is a special value for internal nodes, not used
        top = newNode('$', left->freq + right->freq);
        if (top == NULL) {
            hError |= (1 << 6);
            return NULL;
        }
        top->left = left;
        top->right = right;
        insertMinHeap(minHeap, top);
    }

    // Step 4: The remaining node is the root node and the tree is complete.
    ret_node = extractMin(minHeap);
    osal_mem_free(minHeap);

    return ret_node;
}
 // Adds a number into the data structure.
 void addNum(int num) {
     if(maxHeap.size() == 0 && minHeap.size() == 0) {
         maxHeap.push_back(num);
         return;
     }// if first num to add
     if(maxHeap.size() <= minHeap.size()){
         if(num > minHeap[0]){
             minHeap.push_back(num);
             minHeapify();
             maxHeap.push_back(extractMin());
             maxHeapify();
             //return;
         }else{
             maxHeap.push_back(num);
             maxHeapify();
             //return;
         }
     }else{
         if(num < maxHeap[0]){
             maxHeap.push_back(num);
             maxHeapify();
             minHeap.push_back(extractMax());
             minHeapify();
             //return;
         }else{
             minHeap.push_back(num);
             minHeapify();
             //return;
         }
     }
     if(maxHeap.size()>minHeap.size() + 1){
         minHeap.push_back(extractMax());
         minHeapify();
     }else if(minHeap.size()>maxHeap.size()){
         maxHeap.push_back(extractMin());
         maxHeapify();
     }
 }
Example #14
0
void Prims(int source){
	struct node* adjacent;
	int min;
	CreateHeap(vertices);

	insert(0,source);
	AdjacencyList[source].pri = 0;
	min = extractMin();
	AdjacencyList[min].color = BLUE;
	pi[source] = source;
	while(min!=-1){
	adjacent = AdjacencyList[min].Node;
	while(adjacent!=NULL){

		if(AdjacencyList[adjacent->vertex].color == RED){
			AdjacencyList[adjacent->vertex].pri = adjacent->weight;
			AdjacencyList[adjacent->vertex].color = YELLOW;
			pi[adjacent->vertex] = min;
			insert(AdjacencyList[adjacent->vertex].pri,adjacent->vertex);
		}
		else if(AdjacencyList[adjacent->vertex].color == YELLOW){
			//printf("Here for %d\n,weight = %d,",adjacent->vertex,adjacent->weight);
			if(AdjacencyList[adjacent->vertex].pri > adjacent->weight)
			{
				AdjacencyList[adjacent->vertex].pri = adjacent->weight;
				decreaseKey(AdjacencyList[adjacent->vertex].HeapPoint , AdjacencyList[adjacent->vertex].pri);
				pi[adjacent->vertex] = min;
			}
		}
		adjacent = adjacent->next;
	}
	min = extractMin();	
	if(min!=-1)
	AdjacencyList[min].color = BLUE;
	//printf("Minimum = %d\n",min);
}

}
Example #15
0
// The main function that takes an array of lists from N machines
// and generates the sorted output
void externalSort( ListNode *array[], int N )
{
    // Create a min heap of size equal to number of machines
    MinHeap* minHeap = createMinHeap( N );
 
    // populate first item from all machines
    populateMinHeap( minHeap, array, N );
 
    while ( !isEmpty( minHeap ) )
    {
        ListNode* temp = extractMin( minHeap );
        printf( "%d ",temp->data );
    }
}
void
dijkstra(graph* g, int src)
{
    int v, V = g->V; // getting the number of indices from the graph.
    int dist[V];
    int i,max = 0;

    minHeap* mHeap = createMinHeap(V);

    for(v = 0; v < V; v++)
    {
        dist[v] = MAXINT;
        mHeap->array[v] = createHeapNode(v, dist[v]);
        mHeap->pos[v] = v;
    }
    mHeap->array[src] = createHeapNode(src, dist[src]);
    mHeap->pos[src]   = src;
    dist[src] = 0;
    decreaseKey(mHeap, src, dist[src]);

    mHeap->size = V;

    while ((mHeap->size!=0))
    {
        minHeapNode* mHeapNode = extractMin(mHeap);
        int u = mHeapNode->v;

        node* pNode = g->array[u].head;
        while (pNode != NULL)
        {
            int v = pNode->d;

            if ((isInMinHeap(mHeap, v) && dist[u] != MAXINT) && ((pNode->w + dist[u]) < dist[v]))
            {
                dist[v] = dist[u] + pNode->w;
                decreaseKey(mHeap, v, dist[v]);
            }
            pNode = pNode->next;
        }
    }

    //print the shortest path from distant vertex
    for(i = 0; i < V; i++)
    {
        if(max < dist[i])
            max = dist[i];
    }

    printf("most distant vertex is %d\n",max);
}
Example #17
0
minheapNodePTR build_Huffman_tree( char data[] , int freq[] , int size)
{
	minheapNodePTR left ,right , top;
	minheapPTR hh = createMinHeap(size);
	/* building minheap */
	int i;
	for(i = 0; i < size; i++)
		hh->array[i] = newNode(data[i],freq[i]);
	hh->size = size;
	
	printf("minheap size = %d\n",hh->size);
	print_min_heap(hh);
	buildminHeap(hh);
	print_min_heap(hh);
		/* building minheap END */

	/* huffman ALgo */

	while ( hh->size != 1 )
	{
		left = extractMin(hh);
		right = extractMin(hh);
		printf("%s\n","DEBUGGING INSIDE BUILD build_Huffman_tree \n");
		printf("left data  :%c\n",left->data);
		printf("right data :%c\n",right->data);
		top = newNode('0' , left->freq + right->freq);
		output1_num_of_nodes_in_tree++;
		top->left = left;
		top->right = right;
		insertminHeap(hh , top);
		print_min_heap(hh);
	}
	return extractMin(hh);
	// returns the root node of the Huffman tree
	// with this we can do Postorder , Inorder traversal and also print the huffman codes
}
Example #18
0
int main() {
    if (testIndexes()) {
        testBuildHeap();
        testInsertHeap();
        testDecreaseKey();
        testExtractMin();
        testHeapSort();
    }
    int array[9] = {4,2,3,5,1,6,4,7,9};
    MinHeap* myHeap = buildHeap(array, 9);
    printf("%d", extractMin(myHeap));
    int* a = heapSort(array, 9);

    return 0;
}
Example #19
0
int main()
{
	int ch,a[100], p, n, i, pos;
	
	printf("\nEnter the number of elements  ");
	scanf("%d",&n);
	numm=n;
	
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
		
	buildMinHeap(a, numm);	
	
	printf("\n1.See\n2.extract\n3.insert\n4.update\n5.exit  ");

	while(1)
	{
		printf("\nEnter ur choice  ");
		scanf("%d",&ch);
		
		switch(ch)
		{
			case 1:
				see(a, numm);
				break;
			case 2:
				printf("\nthe min element was %d \n",extractMin(a));
				break;
			case 3:
				printf("\nEnter node to insert  ");
				scanf("%d",&i);
				insert(a,i);
				break;
			case 4:
				printf("\nEnter the index to update ");
				scanf("%d",&p);
				printf("nEnter the node key value ");
				scanf("%d",&i);
				update(a, p, i);
				break;
			case 5:
				return (0);
		}
	}
	return 0;
}
Example #20
0
void mergeKSortedArrays(int arr1[][n], int k)
{
    maxheap *h = createHeap(13);
    int *output = (int *)malloc(sizeof(int)*n*k);
    int i=0, j=0;
    for(i=0;i<n;i++)
    {
      for(j=0;j<k;j++)
      {
	  insertMinHeap(h,arr1[j][i]); 
      }
    }
    for(i=0;i<n*k;i++)
    {
      output[i]=extractMin(h);
      printf("%d ,", output[i]);
    }
}
Example #21
0
File: FibHeap.cpp Project: cran/CRF
int  FibHeap::remove(FibHeapNode *theNode)
{
  FibHeapNode Temp;
  int Result;
  
  if (theNode == NULL) return NOTOK;
  
  Temp.m_neg_infinity_flag = 1;
  Result = decreaseKey(theNode, Temp);
  
  if (Result == OK)
    if (extractMin() == NULL) Result = NOTOK;
    
    if (Result == OK) {
      if (getHeapOwnership()) delete theNode;
      else theNode->m_neg_infinity_flag = 0;
    }
    
    return Result;
}
void dijkstra (HeadList *head_list, int src){
	int V = head_list->V;
	position = malloc(sizeof(int)*V);  // allocates spaces for position array
	values = malloc(sizeof(int)*V);    // allocates spaces for values array
	int y;
	MinHeap *heap = malloc(sizeof*heap*V);  // allocates space for Min Heap struct 
	for (y=0; y<V;y++) {
		heap[y] = malloc(sizeof(MinHeap));
	}
	heapsize = V;
	int v;
	// assign infinite to weight of all node
	for (v=0; v<V; v++) {
		values[v] = INT_MAX;
		heap[v]->id = v;
		heap[v]->value = INT_MAX;
		position[v] = v;
	}
	//except source 0.
	// assign it zero
	heap[src]->value = src;
	heap[src]->id = src;
	position[src] = src;
	values[src] = 0;
	relax(heap, src, values[src]);
	 while (heapsize!=0){
		MinHeap uNode = extractMin(heap);  // return the min node
		int u = uNode->id;
		NodeList node = head_list->head[u]; // to check the node has next node
		while(node != NULL){
			int v = node->dest;
			if (position[v] < heapsize && values[u] != INT_MAX && node->weight + values[u] < values[v]){
				//printf("u is %d and v is %d\n",u,v);
	        	values[v] = values[u] + node->weight;

	            relax(heap, v, values[v]);
	        }
		    node = node->next;
		}
	}
}
Example #23
0
// 删除指定结点
bool deleteFromFibonaciHeap(FibonaciHeap *heap, FibonaciNode *node)
{
	decreaseKey(heap, node, FIBONACI_MINUS_INF);
	return extractMin(heap) == FIBONACI_MINUS_INF;
}
Example #24
0
// The main function that constructs Minimum Spanning Tree (MST)
// using Prim's algorithm
void PrimMST(Graph* graph)
{
    int MSTWeight = 0;
    int V = graph->V;// Get the number of vertices in graph
    int E = graph->E;// Get the number of edges in graph
    int parent[V];   // Array to store constructed MST
    int key[V];      // Key values used to pick minimum weight edge in cut
 
    // minHeap represents set E
    MinHeap* minHeap = createMinHeap(V);
 
    // Initialize min heap with all vertices. Key value of
    // all vertices (except 0th vertex) is initially infinite

    // print edges of MST
    printf("===============================================\n");
    printf("Following are the edges in the constructed MST\n");

    for (int v = 1; v < V; ++v)
    {
        parent[v] = -1;
        key[v] = INT_MAX;
        minHeap->array[v] = newMinHeapNode(v, key[v]);
        minHeap->pos[v] = v;
    }
 
    // Make key value of 0th vertex as 0 so that it
    // is extracted first
    key[0] = 0;
    minHeap->array[0] = newMinHeapNode(0, key[0]);
    minHeap->pos[0]   = 0;
 
    // Initially size of min heap is equal to V
    minHeap->size = V;
 
    // In the followin loop, min heap contains all nodes
    // not yet added to MST.
    while (!isEmpty(minHeap))
    {
        // Extract the vertex with minimum key value
        MinHeapNode* minHeapNode = extractMin(minHeap);
        int u = minHeapNode->v; // Store the extracted vertex number
        // Traverse through all adjacent vertices of u (the extracted
        // vertex) and update their key values
	int i;
	int* adjList = findAdjList(graph,u);
        int size = findAdjListCount(graph, u, NULL, 0);
	//printf("%d->%d\n",adjList[0],adjList[1]);
        //printf("%d\n",size);
	for (i=1;i<size;i++) 
        {
	    int v = adjList[i];
	    // printf("%d\n",v);   
            // If v is not yet included in MST and weight of u-v is
            // less than key value of v, then update key value and
            // parent of v
            if (isInMinHeap(minHeap, v) && findWeight(graph,u,v) < key[v])
            {
                key[v] = findWeight(graph,u,v);
                parent[v] = u;
                decreaseKey(minHeap, v, key[v]);
	    }
	 }
	 MSTWeight += minHeapNode->key;
    }
    int n;
    for (n=1;n<V;n++) {
       printf("Edge: %d -- %d (Weight: %d)\n",parent[n],n,key[n]);
    }
    printf("Total Weight: %d\n", MSTWeight);
    printf("===============================================\n");
}
double findMedianSortedArrays(int A[], int m, int B[], int n)
{
    int mid = (m+n)/2;
    if ((m+n)%2 == 1)
        mid = (m+n+1)/2;
    double median = 0.0;
    
    if (m == 0 && n == 0)
    {
        return 0.0;
    }
    else if (m == 0 && n != 0)
    {
        if (n%2 == 0)
            median = ((double)B[n/2-1]+(double)B[n/2+1-1])/2;
        else
            median = B[(n+1)/2-1];
        return median;
    }
    else if (m != 0 && n == 0)
    {
        if (m%2 == 0)
            median = ((double)A[m/2-1]+(double)A[m/2+1-1])/2;
        else
            median = A[(m+1)/2-1];
        return median;
    }

    int i = m;
    int j = n;
    while (mid > 0 && i > 0 && j > 0)
    {
        if (A[0] < B[0])
        {
            median = extractMin(A, i);
            --i;
        }
        else
        {
            median = extractMin(B, j);
            --j;
        }
        --mid;
    }
    
    while (mid > 0)
    {
        if (i == 0)
        {
            median = extractMin(B, j);
            --j;
        }
        else
        {
            median = extractMin(A, i);
            --i;
        }
        mid--;
    }
    
    if ((m+n)%2 == 0)
    {
        if (i != 0 && j != 0)
        {
            median += min(A[0], B[0]);
        }
        else if (i == 0)
        {
            median += B[0];
        }
        else
        {
            median += A[0];
        }
        median = median/2;
    }
    
    return median;
}
AStarSearch::AStarSearch(MapClass* pMap, UnitClass* pUnit, Coord start, Coord destination) {
    sizeX = pMap->sizeX;
    sizeY = pMap->sizeY;

    mapData = (TileData*) calloc(sizeX*sizeY, sizeof(TileData));
    if(mapData == NULL) {
        throw std::bad_alloc();
    }

    float heuristic = blockDistance(start, destination);
    float smallestHeuristic = heuristic;
    bestCoord = Coord(INVALID_POS,INVALID_POS);

    //if the unit is not directly next to its destination or it is and the destination is unblocked
	if ((heuristic > 1.5) || (pUnit->canPass(destination.x, destination.y) == true)) {

        putOnOpenListIfBetter(start, Coord(INVALID_POS, INVALID_POS), 0.0, heuristic);

        std::vector<short> depthCheckCount(std::min(sizeX, sizeY));

        int numNodesChecked = 0;
        while(openList.empty() == false) {
            Coord currentCoord = extractMin();

            if (MapData(currentCoord).h < smallestHeuristic) {
				smallestHeuristic = MapData(currentCoord).h;
				bestCoord = currentCoord;

				if(currentCoord == destination) {
                    // destination found
                    break;
				}
			}

            if (numNodesChecked < MAX_NODES_CHECKED) {
                //push a node for each direction we could go
                for (int angle=0; angle<=7; angle++) {
                    Coord nextCoord = pMap->getMapPos(angle, currentCoord);
                    if(pUnit->canPass(nextCoord.x, nextCoord.y)) {
                        TerrainClass& nextTerrainTile = pMap->cell[nextCoord.x][nextCoord.y];
                        float g = MapData(currentCoord).g;

                        if((nextCoord.x != currentCoord.x) && (nextCoord.y != currentCoord.y)) {
                            //add diagonal movement cost
                            g += DIAGONALCOST*(pUnit->isAFlyingUnit() ? 1.0 : nextTerrainTile.getDifficulty());
                        } else {
                            g += (pUnit->isAFlyingUnit() ? 1.0 : nextTerrainTile.getDifficulty());
                        }

                        if(pUnit->isAFlyingUnit()) {
                            int numDirectionChanges = abs((pUnit->getAngle() - angle)%NUM_ANGLES);
                            double distanceFromStart = blockDistance(start, nextCoord);

                            if(numDirectionChanges > 2) {
                                if(distanceFromStart <= DIAGONALCOST) {
                                    g += 3.0;
                                } else  if(distanceFromStart <= 2*DIAGONALCOST) {
                                    g += 2.0;
                                }
                            } else if(numDirectionChanges > 1) {
                                if(distanceFromStart <= DIAGONALCOST) {
                                    g += 3.0;
                                } else  if(distanceFromStart <= 2*DIAGONALCOST) {
                                    g += 2.0;
                                }
                            }
                        }

                        if(MapData(currentCoord).parentCoord.x != INVALID_POS)	{
                        //add cost of turning time
                            int posAngle = currentGameMap->getPosAngle(MapData(currentCoord).parentCoord, currentCoord);
                            if (posAngle != angle)
                                g += (1.0/currentGame->objectData.data[pUnit->getItemID()].turnspeed * (double)std::min(abs(angle - posAngle), NUM_ANGLES - std::max(angle, posAngle) + std::min(angle, posAngle)))/((double)BLOCKSIZE);
                        }

                        float h = blockDistance(nextCoord, destination);

                        if(MapData(nextCoord).bClosed == false) {
                            putOnOpenListIfBetter(nextCoord, currentCoord, g, h);
                        }
                    }

                }
            }

            if (MapData(currentCoord).bClosed == false) {

				int depth = std::max(abs(currentCoord.x - destination.x), abs(currentCoord.y - destination.y));

				if(depth < std::min(sizeX,sizeY)) {

                    // calculate maximum number of cells in a square shape
                    // you could look at without success around a destination x,y
                    // with a specific k distance before knowing that it is
                    // imposible to get to the destination.  Each time the astar
                    // algorithm pushes a node with a max diff of k,
                    // depthcheckcount(k) is incremented, if it reaches the
                    // value in depthcheckmax(x,y,k), we know we have done a full
                    // square around target, and thus it is impossible to reach
                    // the target, so we should try and get closer if possible,
                    // but otherwise stop
                    //
                    // Examples on 6x4 map:
                    //
                    //  ......
                    //  ..###.     - k=1 => 3x3 Square
                    //  ..# #.     - (x,y)=(3,2) => Square completely inside map
                    //  ..###.     => depthcheckmax(3,2,1) = 8
                    //
                    //  .#....
                    //  ##....     - k=1 => 3x3 Square
                    //  ......     - (x,y)=(0,0) => Square only partly inside map
                    //  ......     => depthcheckmax(0,0,1) = 3
                    //
                    //  ...#..
                    //  ...#..     - k=2 => 5x5 Square
                    //  ...#..     - (x,y)=(0,1) => Square only partly inside map
                    //  ####..     => depthcheckmax(0,1,2) = 7


                    int x = destination.x;
                    int y = destination.y;
                    int k = depth;
                    int horizontal = std::min(sizeX-1, x+(k-1)) - std::max(0, x-(k-1)) + 1;
                    int vertical = std::min(sizeY-1, y+k) - std::max(0, y-k) + 1;
                    int depthCheckMax = ((x-k >= 0) ? vertical : 0) +  ((x+k < sizeX) ? vertical : 0) + ((y-k >= 0) ? horizontal : 0) +  ((y+k < sizeY) ? horizontal : 0);


                    if (++depthCheckCount[k] >= depthCheckMax) {
                        // we have searched a whole square around destination, it can't be reached
                        break;
                    }
				}

                MapData(currentCoord).bClosed = true;
                numNodesChecked++;
            }
        }

	}


}