예제 #1
0
/*!
*  swapUp()
*
*      Input:  lh (heap)
*              index (of array corresponding to node to be swapped up)
*      Return: 0 if OK, 1 on error
*
*  Notes:
*      (1) This is called after a new item is put on the heap, at the
*          bottom of a complete tree.
*      (2) To regain the heap order, we let it bubble up,
*          iteratively swapping with its parent, until it either
*          reaches the root of the heap or it finds a parent that
*          is in the correct position already vis-a-vis the child.
*/
int MinHeap::swapUp(int  index)
{
	int    ip;  /* index to heap for parent; 1 larger than array index */
	int    ic;  /* index into heap for child */
	double  valp, valc;



	if (index < 0 || index >= this->n)
		return 1;

	ic = index + 1;  /* index into heap: add 1 to array index */
	if (this->direction == L_SORT_INCREASING) 
	{
		while (1) 
		{
			if (ic == 1)  /* root of heap */
				break;
			ip = ic / 2;
			valc = this->ptrArray[ic - 1]->key;
			valp = this->ptrArray[ip - 1]->key;
			if (valp <= valc)
				break;
			SWAP_ITEMS(ip - 1, ic - 1);
			ic = ip;
		}
	}
	else
	{
		/* lh->direction == L_SORT_DECREASING */
		while (1)
		{
			if (ic == 1)  /* root of heap */
				break;
			ip = ic / 2;
			valc = this->ptrArray[ic - 1]->key;
			valp = this->ptrArray[ip - 1]->key;
			if (valp >= valc)
				break;

			SWAP_ITEMS(ip - 1, ic - 1);
			ic = ip;
		}
	}
	return ic;
}
예제 #2
0
/*!
 *  lheapSwapUp()
 *
 *      Input:  lh (heap)
 *              index (of array corresponding to node to be swapped up)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This is called after a new item is put on the heap, at the
 *          bottom of a complete tree.
 *      (2) To regain the heap order, we let it bubble up,
 *          iteratively swapping with its parent, until it either
 *          reaches the root of the heap or it finds a parent that
 *          is in the correct position already vis-a-vis the child.
 */
l_int32
lheapSwapUp(L_HEAP  *lh,
            l_int32  index)
{
l_int32    ip;  /* index to heap for parent; 1 larger than array index */
l_int32    ic;  /* index into heap for child */
l_float32  valp, valc;

  PROCNAME("lheapSwapUp");

  if (!lh)
      return ERROR_INT("lh not defined", procName, 1);
  if (index < 0 || index >= lh->n)
      return ERROR_INT("invalid index", procName, 1);

  ic = index + 1;  /* index into heap: add 1 to array index */
  if (lh->direction == L_SORT_INCREASING) {
      while (1) {
          if (ic == 1)  /* root of heap */
              break;
          ip = ic / 2;
          valc = *(l_float32 *)(lh->array[ic - 1]);
          valp = *(l_float32 *)(lh->array[ip - 1]);
          if (valp <= valc)
             break;
          SWAP_ITEMS(ip - 1, ic - 1);
          ic = ip;
      }
  }
  else {  /* lh->direction == L_SORT_DECREASING */
      while (1) {
          if (ic == 1)  /* root of heap */
              break;
          ip = ic / 2;
          valc = *(l_float32 *)(lh->array[ic - 1]);
          valp = *(l_float32 *)(lh->array[ip - 1]);
          if (valp >= valc)
             break;
          SWAP_ITEMS(ip - 1, ic - 1);
          ic = ip;
      }
  }
  return 0;
}
예제 #3
0
/*!
*  sortStrictOrder()
*
*      Input:  lh (heap, with internal array)
*      Return: 0 if OK, 1 on error
*
*  Notes:
*      (1) This sorts a heap into strict order.
*      (2) For each element, starting at the end of the array and
*          working forward, the element is swapped with the head
*          element and then allowed to swap down onto a heap of
*          size reduced by one.  The result is that the heap is
*          reversed but in strict order.  The array elements are
*          then reversed to put it in the original order.
*/
int MinHeap::sortStrictOrder()
{
	int  i, index, size;

	size = this->n;  /* save the actual size */

	for (i = 0; i < size; i++) 
	{
		index = size - i;
		SWAP_ITEMS(0, index - 1);
		this->n--;  /* reduce the apparent heap size by 1 */
		swapDown();
	}

	this->n = size;  /* restore the size */

	for (i = 0; i < size / 2; i++)  /* reverse */
		SWAP_ITEMS(i, size - i - 1);

	return 0;
}
예제 #4
0
파일: heap.c 프로젝트: stweil/leptonica-old
/*!
 *  lheapSortStrictOrder()
 *
 *      Input:  lh (heap, with internal array)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This sorts a heap into strict order.
 *      (2) For each element, starting at the end of the array and
 *          working forward, the element is swapped with the head
 *          element and then allowed to swap down onto a heap of
 *          size reduced by one.  The result is that the heap is
 *          reversed but in strict order.  The array elements are
 *          then reversed to put it in the original order.
 */
l_int32
lheapSortStrictOrder(L_HEAP  *lh)
{
l_int32  i, index, size;

  PROCNAME("lheapSortStrictOrder");

  if (!lh)
      return ERROR_INT("lh not defined", procName, 1);

  size = lh->n;  /* save the actual size */
  for (i = 0; i < size; i++) {
      index = size - i;
      SWAP_ITEMS(0, index - 1);
      lh->n--;  /* reduce the apparent heap size by 1 */
      lheapSwapDown(lh);
  }
  lh->n = size;  /* restore the size */

  for (i = 0; i < size / 2; i++)  /* reverse */
      SWAP_ITEMS(i, size - i - 1);

  return 0;
}
예제 #5
0
파일: heap.c 프로젝트: stweil/leptonica-old
/*!
 *  lheapSwapDown()
 *
 *      Input:  lh (heap)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This is called after an item has been popped off the
 *          root of the heap, and the last item in the heap has
 *          been placed at the root.
 *      (2) To regain the heap order, we let it bubble down,
 *          iteratively swapping with one of its children.  For a
 *          decreasing sort, it swaps with the largest child; for
 *          an increasing sort, the smallest.  This continues until
 *          it either reaches the lowest level in the heap, or the
 *          parent finds that neither child should swap with it
 *          (e.g., for a decreasing heap, the parent is larger
 *          than or equal to both children).
 */
l_int32
lheapSwapDown(L_HEAP  *lh)
{
l_int32    ip;  /* index to heap for parent; 1 larger than array index */
l_int32    icr, icl;  /* index into heap for left/right children */
l_float32  valp, valcl, valcr;

  PROCNAME("lheapSwapDown");

  if (!lh)
      return ERROR_INT("lh not defined", procName, 1);
  if (lheapGetCount(lh) < 1)
      return 0;

  ip = 1;  /* index into top of heap: corresponds to array[0] */
  if (lh->direction == L_SORT_INCREASING) {
      while (1) {
          icl = 2 * ip;
          if (icl > lh->n)
             break;
          valp = *(l_float32 *)(lh->array[ip - 1]);
          valcl = *(l_float32 *)(lh->array[icl - 1]);
          icr = icl + 1;
          if (icr > lh->n) {  /* only a left child; no iters below */
              if (valp > valcl)
                  SWAP_ITEMS(ip - 1, icl - 1);
              break;
          } else {  /* both children exist; swap with the smallest if bigger */
              valcr = *(l_float32 *)(lh->array[icr - 1]);
              if (valp <= valcl && valp <= valcr)  /* smaller than both */
                  break;
              if (valcl <= valcr) {  /* left smaller; swap */
                  SWAP_ITEMS(ip - 1, icl - 1);
                  ip = icl;
              } else { /* right smaller; swap */
                  SWAP_ITEMS(ip - 1, icr - 1);
                  ip = icr;
              }
          }
      }
  } else {  /* lh->direction == L_SORT_DECREASING */
      while (1) {
          icl = 2 * ip;
          if (icl > lh->n)
             break;
          valp = *(l_float32 *)(lh->array[ip - 1]);
          valcl = *(l_float32 *)(lh->array[icl - 1]);
          icr = icl + 1;
          if (icr > lh->n) {  /* only a left child; no iters below */
              if (valp < valcl)
                  SWAP_ITEMS(ip - 1, icl - 1);
              break;
          } else {  /* both children exist; swap with the biggest if smaller */
              valcr = *(l_float32 *)(lh->array[icr - 1]);
              if (valp >= valcl && valp >= valcr)  /* bigger than both */
                  break;
              if (valcl >= valcr) {  /* left bigger; swap */
                  SWAP_ITEMS(ip - 1, icl - 1);
                  ip = icl;
              } else {  /* right bigger; swap */
                  SWAP_ITEMS(ip - 1, icr - 1);
                  ip = icr;
              }
          }
      }
  }

  return 0;
}
예제 #6
0
/*!
*  swapDown()
*
*      Input:  lh (heap)
*      Return: 0 if OK, 1 on error
*
*  Notes:
*      (1) This is called after an item has been popped off the
*          root of the heap, and the last item in the heap has
*          been placed at the root.
*      (2) To regain the heap order, we let it bubble down,
*          iteratively swapping with one of its children.  For a
*          decreasing sort, it swaps with the largest child; for
*          an increasing sort, the smallest.  This continues until
*          it either reaches the lowest level in the heap, or the
*          parent finds that neither child should swap with it
*          (e.g., for a decreasing heap, the parent is larger
*          than or equal to both children).
*/
int MinHeap::swapDown()
{
	int    ip;  /* index to heap for parent; 1 larger than array index */
	int    icr, icl;  /* index into heap for left/right children */
	double  valp, valcl, valcr;

	if (getCount() < 1)
		return 0;

	ip = 1;  /* index into top of heap: corresponds to array[0] */
	if (this->direction == L_SORT_INCREASING) 
	{
		while (1) 
		{
			icl = 2 * ip;
			if (icl > this->n)
				break;
			valp = this->ptrArray[ip - 1]->key;
			valcl = this->ptrArray[icl - 1]->key;
			icr = icl + 1;
			if (icr > this->n)
			{  
				/* only a left child; no iters below */
				if (valp > valcl)
					SWAP_ITEMS(ip - 1, icl - 1);
				break;
			}
			else
			{  
				/* both children present; swap with the smallest if bigger */
				valcr = this->ptrArray[icr - 1]->key;
				if (valp <= valcl && valp <= valcr)  /* smaller than both */
					break;
				if (valcl <= valcr)
				{  
					/* left smaller; swap */
					SWAP_ITEMS(ip - 1, icl - 1);
					ip = icl;
				}
				else
				{ 
					/* right smaller; swap */
					SWAP_ITEMS(ip - 1, icr - 1);
					ip = icr;
				}
			}
		}
	}
	else
	{
		/* lh->direction == L_SORT_DECREASING */
		while (1)
		{
			icl = 2 * ip;
			if (icl > this->n)
				break;
			valp = this->ptrArray[ip - 1]->key;
			valcl = this->ptrArray[icl - 1]->key;
			icr = icl + 1;
			if (icr > this->n)
			{ 
				/* only a left child; no iters below */
				if (valp < valcl)
					SWAP_ITEMS(ip - 1, icl - 1);
				break;
			}
			else
			{
				/* both children present; swap with the biggest if smaller */
				valcr = this->ptrArray[icr - 1]->key;
				if (valp >= valcl && valp >= valcr)  /* bigger than both */
					break;
				if (valcl >= valcr) 
				{
					/* left bigger; swap */
					SWAP_ITEMS(ip - 1, icl - 1);
					ip = icl;
				}
				else
				{
					/* right bigger; swap */
					SWAP_ITEMS(ip - 1, icr - 1);
					ip = icr;
				}
			}
		}
	}
	return 0;
}
예제 #7
0
// sort LR_ITEM_SET list for easy comparison
LR_ITEM_SET* Sort(LR_ITEM_SET* I)
{
    LR_ITEM_SET* itr;
    LR_ITEM* heap;
    int i, size;
    
    if (I == NULL) return I;
    
    // count elements [O(N)]
    size = 0;
    for (itr = I; itr; itr = itr->next)
    {
        size++;
    }
    
    // allocate heap [O(1)]
    heap = malloc(sizeof(LR_ITEM) * size);
    
    // add items to the heap [O(N log N)]
    for (itr = I, i = 0; itr; itr = itr->next, i++)
    {
        heap[i] = itr->item;
        int a = i; int b = (i-1)/2;
        while (a > 0 && CompareItems(heap[a], heap[b]) < 0)
        {
            SWAP_ITEMS(&heap[a], &heap[b]);
            a = b;
            b = (b-1)/2;
        }
    }
    
    // pop items off the heap [O(N log N)]
    for (itr = I; itr; itr = itr->next)
    {
        itr->item = heap[0];
        size--;
        heap[0] = heap[size];
        
        int j = 0;
        int a = 1; int b = 2;
        while (j < size &&
               ((a < size && CompareItems(heap[j], heap[a]) > 0)
             || (b < size && CompareItems(heap[j], heap[b]) > 0)))
        {
            if (b < size && CompareItems(heap[a], heap[b]) > 0)
            {
                SWAP_ITEMS(&heap[b], &heap[j]);
                j = b;
            }
            else
            {
                SWAP_ITEMS(&heap[a], &heap[j]);
                j = a;
            }
            a = 2*j + 1;
            b = 2*j + 2;
        }
    }
    
    // free memory [O(1)]
    free(heap);
    return I;
}