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); } }
/** * 堆排序 * @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; }
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); } }
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; } }
void insert(Heap* hp,char* data) { hp->root = insertNode(hp->root,data); adjustHeap(hp); }