ListNode* mergeKLists(vector<ListNode*>& lists)
{
	int i = 0;
	vector<ListNode*> nodes;
	ListNode *newHead = new ListNode(-1);
	ListNode *p = newHead;
	init(lists, nodes);
	for (i = (nodes.size() - 1) / 2; i >= 0; i--)
	{
		adjustHeap(nodes, i);
	}
	if (nodes.size() == 0)
		return newHead->next;
	while (nodes[0]->val!=MAX_INT)
	{
		ListNode *min = nodes[0];
		p->next= min;
		p = p->next;
		min = min->next;
		if (min == NULL)
			min = new ListNode(MAX_INT);
		nodes[0] = min;
		adjustHeap(nodes, 0);
	}

	return newHead->next;
}
/**
 * Adjusts heap to maintain the heap property.
 * @param heap
 * @param last  index to adjust up to.
 * @param position  index where adjustment starts.
 * @param compare  pointer to compare function.
 */
void adjustHeap(DynamicArray* heap, int last, int position, compareFunction compare)
{


int leftChild = 2 * position + 1; 
int rightChild = 2 * position + 2;
int smallestChild;
/* we have two children */
if (rightChild < last) { 
if (compare(dyGet(heap, leftChild), dyGet(heap,rightChild)) == -1)
 	 smallestChild = leftChild;
else
	 smallestChild = rightChild;
//get index of smallest child


    if (compare(dyGet(heap, position), dyGet(heap, smallestChild)) == 1) {
	dySwap(heap, position, smallestChild);
	adjustHeap(heap, last, smallestChild, compare);
}
}

else if (leftChild < last) { 
if (compare(dyGet(heap, position), dyGet(heap, leftChild)) == 1) {
dySwap(heap, position, leftChild);
adjustHeap(heap, last, leftChild, compare);
}
}
}
//把一个子树构建成一个max-heap.可以优化里面的代码,写的不够简练,但是逻辑很清楚
//http://jingyan.baidu.com/article/5225f26b057d5de6fa0908f3.html
void adjustHeap(int a[], int i, int n){
    int leftChild;
    int tmp;
    
    //i的左右孩子都在
    if (2 * i + 1 < n - 1 && 2 * i + 2 <= n - 1 ) {
        leftChild = i * 2 + 1;
        
        //a[i]大于左右孩子,表示i子树是max-heap了,所以直接返回
        if (a[i] > a[leftChild] && a[i] > a[leftChild + 1]) {
            return;
        }
        else{
            //左孩子大,i与左孩子交换,并递归处理左子树
            if (a[leftChild] > a[leftChild + 1]) {
                tmp = a[i];
                a[i] = a[leftChild];
                a[leftChild] = tmp;
                adjustHeap(a, leftChild, n);
            }
            //右孩子大,i与右孩子交换,并递归处理右子树
            else{
                tmp = a[i];
                a[i] = a[leftChild + 1];
                a[leftChild + 1] = tmp;
                adjustHeap(a, leftChild + 1, n);
            }
        }
    }
    //i只有左孩子
    else if (2 * i + 1 <= n - 1){
        leftChild = i * 2 + 1;
        
        //左孩子大,i与左孩子交换,并递归处理左子树
        if (a[leftChild] > a[i]) {
            tmp = a[i];
            a[i] = a[leftChild];
            a[leftChild] = tmp;
            adjustHeap(a, leftChild, n);
        }
        else{
            return;
        }
    }
    //i没孩子,直接返回
    else{
        return;
    }
}
void constructHeap(int *p,int n)
{
	for (int i = n / 2 - 1; i >= 0; i--)
	{
		adjustHeap(p, i, n);
	}
}
void heapSort(int a[], int n){
    //对每个非叶子节点为root的子树建立max-heap,最后形成一个max-heap
    for (int i = n / 2; i >=0; i--) {
        adjustHeap(a, i, n);
    }
    
    int tmp;
    //0~i是max-heap,i+1~n-1是有序表,每次从max-heap中去除最大的放到有序表中
    for (int i = n - 1; i > 0; i--) {
        tmp = a[0];
        a[0] = a[i];
        a[i] = tmp;
        
        adjustHeap(a, 0, i);
    }
}
int deleteHeap(int *p, int n)
{
	int tmp = p[0];
	p[0] = p[n - 1];
	p[n - 1] = tmp;
	adjustHeap(p, 0, n - 1);
	return tmp;
}
void heapSort(int data[], int length)
{
    if(data==NULL || length<=0)
        return;
    int i=0;
    for(i=length/2-1; i>=0; --i)
    {
        adjustHeap(data, i, length-1);
    }
    for(i=length-1; i>0; --i)
    {
        data[i] ^= data[0];
        data[0] ^= data[i];
        data[i] ^= data[0];
        adjustHeap(data, 0, i-1);
    }
}
/**
 * Builds a valid heap from an arbitrary array.
 * @param heap  array with elements in any order.
 * @param compare  pointer to compare function.
 */
void buildHeap(DynamicArray* heap, compareFunction compare)
{
   int last = (dySize(heap) / 2) - 1;
	int x;
   for (x = last; x >= 0; x--)
{
	adjustHeap(heap, heap->size, x, compare);
}
}
Exemple #9
0
/**
* 堆排序
* @param array  待排序的数组
* @param len  待排序数组的长度
* @return void
*/
void HeapSort(int array[],int len)
{
   int i;
   // 构造初始小顶堆
   for(i = len/2-1;i >= 0;i--)
   {
      adjustHeap(array,i,len);
   }
   // test
   PrintArray(array,len,"初始化小顶堆后:");
   // test
   printf("堆排序后:\n");
   for(i = len - 1;i >= 0;i--)
   {
      printf("%d ",array[0]);
      swap(&array[0],&array[i]);
      adjustHeap(array,0,i);
   }
}
int heapSort() {
    int t, k;
    t = 0;
    for (k = 0; k < n; k = k + 1) {
        t = a[0];
        a[0] = a[n-k-1];
        a[n-k-1] = t;
        adjustHeap(n-k-1);
    }
    return 0;
}
Exemple #11
0
void heap_sort(int A[], int n) {
	int i,temp;
	
	// build the heap from array
	int begin = n/2 - 1;  //the last node that has no leaf child
	for (i = begin; i >= 0; i--){
		adjustHeap(A, i, n);
	}
	
	while (n > 1){
		/*
		* remove the rightmost leaf at the deepest level and use it for the new root
		* swap root with the rightmost node at the deepest level, which means swap the first and last element of the array.
		*/
		temp = A[n-1];  
		A[n-1] = A[0];
		A[0] = temp;
		n--;        //heap size decrease by 1
		
		adjustHeap(A, 0, n);
	}
}
Exemple #12
0
void testAdjustHeap(CuTest* test)
{
    const int n = 100;
    Task* tasks = createTasks(n);
    for (int j = 0; j < n; j++)
    {
        DynamicArray* heap = dyNew(1);
        for (int i = 0; i < n; i++)
        {
            dyAdd(heap, &tasks[i]);
        }
        for (int i = 0; i < n; i++)
        {
            dyPut(heap, &tasks[rand() % n], 0);
            adjustHeap(heap, dySize(heap) - 1, 0, taskCompare);
            assertHeapProperty(test, heap);
        }
        dyDelete(heap);
    }
    free(tasks);
}
void
hitMatrix::filter(encodedQuery *query, bool isReverse) {

  if (_hitsLen == 0)
    return;

  //  Decide on the minimum quality values; we pick the larger of
  //  the fixed lengths, and the sequence length * coverage.
  //
  uint32   minLengthSingle   = (uint32)(config._minCoverageSingle   * _qsLen);
  uint32   minLengthMultiple = (uint32)(config._minCoverageMultiple * _qsLen);

  if (minLengthSingle < config._minLengthSingle)
    minLengthSingle = config._minLengthSingle;

  if (minLengthMultiple < config._minLengthMultiple)
    minLengthMultiple = config._minLengthMultiple;



  //  First, sort by the dsPos.  This is done so that we can find all the hits for
  //  a specific scaffold.
  //
  sort_dsPos();


  //  Now, while there are hits left....
  //
  uint32  firstHit   = 0;
  uint32  lastHit    = 0;
  uint32  currentSeq = 0;

  while (firstHit < _hitsLen) {

    //  Move the currentSeq until the firstHit is below it.
    //
    while ((currentSeq < config._dbSTREAM->numberOfSequences()) &&
           (config._dbSTREAM->startOf(currentSeq) <= _hits[firstHit]._dsPos))
      currentSeq++;

    //
    //  currentSeq is now the sequence AFTER the one that we want hits in.
    //

    //  Find the first hit that is in currentSeq.  If this is the last sequence,
    //  then, of course, all remaining hits are in it.
    //
    if (currentSeq < config._dbSTREAM->numberOfSequences()) {
      lastHit = firstHit + 1;
      while ((lastHit < _hitsLen) &&
             (_hits[lastHit]._dsPos < config._dbSTREAM->startOf(currentSeq)))
        lastHit++;
    } else {
      lastHit = _hitsLen;
    }

    //  Drop back one sequence; this is the sequence the hits are in.
    //
    currentSeq--;

#if TRACE
    fprintf(stdout, "Hits are in sequence %d\n", config._dbSTREAM->IIDOf(currentSeq));
    fprintf(stdout, "filtering %u hits -- first = %u last = %u.\n", _hitsLen, firstHit, lastHit);

#if 0
    fprintf(stdout, "UNSORTED\n");
    for (uint32 i=firstHit; i<lastHit; i++)
      fprintf(stdout, "hit at qs=%4u ds=%6u diag=%6u\n",
              _hits[i]._qsPos,
              _hits[i]._dsPos,
              _hits[i]._diagonalID);
#endif
#endif

    //  Adjust the hits to be relative to the start of this sequence
    //
    for (uint32 i=firstHit; i<lastHit; i++)
      _hits[i]._dsPos -= config._dbSTREAM->startOf(currentSeq);

    //  Sort them, if needed.
    //
    if (lastHit - firstHit > 1) {

      //  We cheat; heapsort isn't too friendly to sorting the middle of
      //  an array, so we make a new array in the middle!
      //
      diagonalLine  *hitsToSort = _hits + firstHit;

      //  Build the heap.  I initially thought this could be done at the
      //  same time as the scan for the last hit, but it can't (easily)
      //
      for (int32 i=(lastHit - firstHit)/2 - 1; i>=0; i--)
#ifdef WITHOUT_DIAGONALID
        adjustHeap(hitsToSort, i, lastHit - firstHit, _qsLen);
#else
        adjustHeap(hitsToSort, i, lastHit - firstHit);
#endif

      //  Sort the hits be diagonal.  This is the second part of
      //  heap sort -- Interchange the new maximum with the element
      //  at the end of the tree
      //
      for (uint32 i=lastHit - firstHit - 1; i>0; i--) {
        uint32  q  = hitsToSort[i]._qsPos;
        uint32  d  = hitsToSort[i]._dsPos;
#ifndef WITHOUT_DIAGONALID
        uint32  l  = hitsToSort[i]._diagonalID;
#endif
        
        hitsToSort[i]._qsPos      = hitsToSort[0]._qsPos;
        hitsToSort[i]._dsPos      = hitsToSort[0]._dsPos;
#ifndef WITHOUT_DIAGONALID
        hitsToSort[i]._diagonalID = hitsToSort[0]._diagonalID;
#endif

        hitsToSort[0]._qsPos      = q;
        hitsToSort[0]._dsPos      = d;
#ifndef WITHOUT_DIAGONALID
        hitsToSort[0]._diagonalID = l;
#endif      

#ifdef WITHOUT_DIAGONALID
        adjustHeap(hitsToSort, 0, i, _qsLen);
#else
        adjustHeap(hitsToSort, 0, i);
#endif
      }
    }


    //  Check the sorting
    //
#if 0
#if 0
    fprintf(stderr, "sort by diagonal:\n");
    for (uint32 i=firstHit; i<lastHit; i++)
      fprintf(stderr, "%8u %8u %8u\n", _hits[i]._diagonalID, _hits[i]._qsPos, _hits[i]._dsPos);
#endif
    for (uint32 i=firstHit; i<lastHit-1; i++) {
      if (_hits[i]._diagonalID > _hits[i+1]._diagonalID) {
        fprintf(stderr, "sort by diagonal failed.\n");
        exit(1);
      }
    }
#endif



#if TRACE
#if 0
    fprintf(stdout, "SORTED\n");
    for (uint32 i=firstHit; i<lastHit; i++)
      fprintf(stdout, "hit at qs=%4u ds=%6u diag=%6u\n",
              _hits[i]._qsPos,
              _hits[i]._dsPos,
              _hits[i]._diagonalID);
#endif

    fprintf(stdout, "FILTERED\n");
#endif

    //  Filter them
    //
#ifdef WITHOUT_DIAGONALID
    uint32  frstDiagonal = _qsLen - _hits[firstHit]._qsPos - 1 + _hits[firstHit]._dsPos;
    uint32  lastDiagonal = frstDiagonal;
#else
    uint32  frstDiagonal = _hits[firstHit]._diagonalID;
    uint32  lastDiagonal = _hits[firstHit]._diagonalID;
#endif
    uint32  qsLow        = _hits[firstHit]._qsPos;
    uint32  qsHigh       = _hits[firstHit]._qsPos;
    uint32  dsLow        = _hits[firstHit]._dsPos;
    uint32  dsHigh       = _hits[firstHit]._dsPos;

    //  Create a new merCovering, and space to count the number of mers in a match
    //
    merCovering *IL = new merCovering(config._merSize);

    for (uint32 i=firstHit; i<lastHit; i++) {
#ifdef WITHOUT_DIAGONALID
      uint32 thisDiagonalID = _qsLen - _hits[i]._qsPos - 1 + _hits[i]._dsPos;
#else
      uint32 thisDiagonalID = _hits[i]._diagonalID;
#endif



#if TRACE
      fprintf(stdout, "hit[qs=%6u ds=%7u d=%7u]  box[qs=%6u-%6u ds=%7u-%7u d=%7u-%7u]  ",
              _hits[i]._qsPos,
              _hits[i]._dsPos,
              thisDiagonalID,
              qsLow, qsHigh, dsLow, dsHigh, frstDiagonal, lastDiagonal);
#endif

      //  Unconditionally extend if the diagonal difference is small.
      //
      if (lastDiagonal + config._maxDiagonal >= thisDiagonalID) {
        lastDiagonal = thisDiagonalID;
        if (qsLow  > _hits[i]._qsPos)   qsLow  = _hits[i]._qsPos;
        if (qsHigh < _hits[i]._qsPos)   qsHigh = _hits[i]._qsPos;
        if (dsLow  > _hits[i]._dsPos)   dsLow  = _hits[i]._dsPos;
        if (dsHigh < _hits[i]._dsPos)   dsHigh = _hits[i]._dsPos;
        IL->addMer(_hits[i]._qsPos);
#if TRACE
        fprintf(stdout, "extend qs=%9u-%9u ds=%9u-%9u  diag=%9u-%9u (diagonal)\n",
                qsLow, qsHigh, dsLow, dsHigh, frstDiagonal, lastDiagonal);
#endif
        continue;
      }


      //  XXX:  Prototype for extending only if the next hit is near
      //  the last hit.
      //
      if (((dsHigh <= _hits[i]._dsPos) && (_hits[i]._dsPos - dsHigh <= config._maxIntronLength)) ||
          ((dsHigh >= _hits[i]._dsPos) && (dsHigh - _hits[i]._dsPos <= config._maxIntronLength))) {

        //  Extend into multiple-exon like things only if the input
        //  sequence is long.
        //
        if (_qsLen > config._smallSequenceCutoff) {

          //  Extend if the qsOverlap is small (or nonexistant)
          //
          if ((qsHigh + config._merSize) < (_hits[i]._qsPos + config._qsOverlap)) {
            lastDiagonal = thisDiagonalID;
            if (qsLow  > _hits[i]._qsPos)   qsLow  = _hits[i]._qsPos;
            if (qsHigh < _hits[i]._qsPos)   qsHigh = _hits[i]._qsPos;
            if (dsLow  > _hits[i]._dsPos)   dsLow  = _hits[i]._dsPos;
            if (dsHigh < _hits[i]._dsPos)   dsHigh = _hits[i]._dsPos;
            IL->addMer(_hits[i]._qsPos);
#if TRACE
            fprintf(stdout, "extend qs=%9u-%9u ds=%9u-%9u  diag=%9u-%9u (qsOverlap)\n",
                    qsLow, qsHigh, dsLow, dsHigh, frstDiagonal, lastDiagonal);
#endif
            continue;
          }

          //  Extend if the dsOverlap is small (or nonexistant)
          //
          if (_hits[i]._dsPos < (dsLow + config._dsOverlap)) {
            lastDiagonal = thisDiagonalID;
            if (qsLow  > _hits[i]._qsPos)   qsLow  = _hits[i]._qsPos;
            if (qsHigh < _hits[i]._qsPos)   qsHigh = _hits[i]._qsPos;
            if (dsLow  > _hits[i]._dsPos)   dsLow  = _hits[i]._dsPos;
            if (dsHigh < _hits[i]._dsPos)   dsHigh = _hits[i]._dsPos;
            IL->addMer(_hits[i]._qsPos);
#if TRACE
            fprintf(stdout, "extend qs=%9u-%9u ds=%9u-%9u  diag=%9u-%9u (dsOverlap)\n",
                    qsLow, qsHigh, dsLow, dsHigh, frstDiagonal, lastDiagonal);
#endif
            continue;
          }
        }
      }  //  XXX:  End prototype

#if TRACE
      fprintf(stdout, "close current cluster.\nGOOD?  qsCov=%u; >= %u or %u?  diag: %u < 25?\n",
              qsHigh - qsLow,
              minLengthSingle,
              minLengthMultiple,
              lastDiagonal - frstDiagonal);
#endif


      //  Save the current cluster and start a new one?
      //
      uint32 qCov = IL->sumOfLengths();
      if ((qCov >= minLengthMultiple) ||
          ((lastDiagonal - frstDiagonal < 25) && (qCov >= minLengthSingle))) {
#if TRACE
        fprintf(stdout, "add match!\n");
#endif
        addMatch(qsLow,
                 qsHigh + config._merSize,
                 dsLow,
                 dsHigh + config._merSize,
                 IL);
        IL = new merCovering(config._merSize);
      }

      if (IL)
        IL->clear();

#if TRACE
      fprintf(stdout, "reset!\n");
#endif

      frstDiagonal = thisDiagonalID;
      lastDiagonal = thisDiagonalID;
      qsLow        = _hits[i]._qsPos;
      qsHigh       = _hits[i]._qsPos;
      dsLow        = _hits[i]._dsPos;
      dsHigh       = _hits[i]._dsPos;

#if TRACE
      fprintf(stdout, "hit[qs=%6u ds=%7u d=%7u]  box[qs=%6u-%6u ds=%7u-%7u d=%7u-%7u]  (initial hit)\n",
              _hits[i]._qsPos,
              _hits[i]._dsPos,
              _qsLen - _hits[i]._qsPos - 1 + _hits[i]._dsPos,
              qsLow, qsHigh, dsLow, dsHigh, frstDiagonal, lastDiagonal);
#endif

      IL->addMer(_hits[i]._qsPos);
    }

    //  Save the final cluster?
    //
    uint32 qCov = IL->sumOfLengths();
    if ((qCov >= minLengthMultiple) ||
        ((lastDiagonal - frstDiagonal < 21) && (qCov >= minLengthSingle))) {
      addMatch(qsLow,
               qsHigh + config._merSize,
               dsLow,
               dsHigh + config._merSize,
               IL);
        IL = 0;
    }

    //  Delete any remaining IL
    //
    delete IL;



    //  Merge and print the matches
    //
    trapMatch     *n  = 0L;
    uint32         ML = 0;

    while (_matches) {

      //  Save the current match, then delete it.
      //
      dsLow      = _matches->_dsLo;
      dsHigh     = _matches->_dsHi;
      IL         = _matches->_IL;
      ML         = IL->sumOfLengths();

      n = _matches;
      _matches = _matches->_next;
      delete n;

#if TRACE
      fprintf(stdout, "Merge: %8u %8u\n", dsLow, dsHigh);
#endif

      //  Assimilate as many of the remaining matches as possible.
      //
      //  Think of this as first reversing the list, then merging as
      //  long as (dsHigh + 1000 > _matches->_dsLo).  But since we
      //  don't reverse the list, we can map:
      //    dsHigh            --> _matches->dsHi
      //    _matches->_dsLo   --> dsLow
      //  where dsHigh and dsLow are the values for the extended match.
      //
      while (_matches && (dsLow < _matches->_dsHi + 5000)) {

        //  Combine the two merCoverings
        //
        IL->merge(_matches->_IL);
        ML += _matches->_IL->sumOfLengths();

        //  The start of the new match might be after the start of the
        //  merged region.  (Only rarely is it before)
        //
        if (dsLow > _matches->_dsLo)
          dsLow = _matches->_dsLo;

        //  The end of current match is always greater than the end of the
        //  new match!
        //
        //dsHigh = _matches->_dsHi;

#if TRACE
        fprintf(stdout, "Merge: %8u %8u -> %8u %8u\n", _matches->_dsLo, _matches->_dsHi, dsLow, dsHigh);
#endif

        n = _matches;
        _matches = _matches->_next;
        delete n->_IL;
        delete n;
      }


      if (config._binaryOutput) {
        aHit a;
      
        a._forward   = !isReverse;
        a._merged    = false;
        a._qsIdx     = _qsIdx;
        a._dsIdx     = config._dbSTREAM->IIDOf(currentSeq);
        a._dsLo      = dsLow;
        a._dsHi      = dsHigh;
        a._covered   = IL->sumOfLengths();
        a._matched   = ML;
        a._numMers   = _qsMers;

        query->addOutput(&a, sizeof(aHit));
      } else {
        char  line[128];

        sprintf(line, "-%c -e "uint32FMT" -D "uint32FMT" "uint32FMT" "uint32FMT" -M "uint32FMT" "uint32FMT" "uint32FMT"\n",
                isReverse ? 'r' : 'f', _qsIdx,
                config._dbSTREAM->IIDOf(currentSeq),
                dsLow, dsHigh, IL->sumOfLengths(), ML, _qsMers);

        query->addOutput(line, 0);
      }

      delete IL;
    }

    //  All done with these hits.  Move to the next set.
    //
    firstHit = lastHit;
  }
}
Exemple #14
0
void insert(Heap* hp,char* data)
{
  hp->root = insertNode(hp->root,data);
  adjustHeap(hp);
}