Пример #1
0
//Partition the array into two halves and return the
//index about which the array is partitioned
int partition(int rows, int cols, int colToSortOn, double * array, 
	int left, int right)
{
	//Makes the leftmost element a good pivot,
	//specifically the median of medians
	findMedianOfMedians(rows, cols, colToSortOn, array, left, right);

	int 
		pivotIndex = left, index = left, 
		i;
	double 
		* colToSort = array+colToSortOn*rows,
		pivotValue = colToSort[pivotIndex];
 
	swapRows(rows, cols, array, pivotIndex, right);

	for(i = left; i < right; i++) {
		if(colToSort[i] < pivotValue) {
			swapRows(rows, cols, array, i, index);
			index += 1;
		}
	}
	swapRows(rows, cols, array, right, index);
	return index;
}
Пример #2
0
					 //  |   |   |   |    |
					 //  v   v   v   v    v
	// * * * * *     //  0   2   45  77  100   // 0    45   77   2    100           //  *    *   *    2   100
	// * * * * *     //  2   66  51  78  101   // 2    51   78   66   101			//  *    *   *   66   101
	// * * * * *     //  6   90  52  79  102   // 6    52   79   90   102 <<----	// 6    52 |79|  90   102 
	// * * * * *     //  89  91  65  90  200   // 89   65   90   91   200			// 89   65   *    *    *
	// * * * * *     //  200 100 98  99  250   // 200  98   99   100  250			// 200  98   *    *    *
	int findMedianOfMedians(std::vector<int>& input, int left, int right)
	{
		std::vector<int> medianVecs;
		for (int rangeCounter = left; rangeCounter < right;)
		{
			std::vector<int> fiveElem;
			for (int i = 0; i < 5 && rangeCounter < right; ++i) /// probably switch to sort directly in the inputvector this could help to reduce memory allocs.. 
			{
				//std::cout << input[left + rangeCounter] << " ";
				fiveElem.push_back(input[rangeCounter]);
				++rangeCounter;
			}
			std::sort(fiveElem.begin(), fiveElem.end());
			//std::cout << std::endl << "m: " << fiveElem[static_cast<int> (fiveElem.size() / 2)] << std::endl;
			medianVecs.push_back(fiveElem[static_cast<int> (fiveElem.size() / 2)]);
		}
		//std::cout << "---------------------------" << std::endl;
		if (medianVecs.size() <= 5)
		{
			std::sort(medianVecs.begin(), medianVecs.end());
			return medianVecs[(medianVecs.size() - 1) / 2];
		}
		else
		{
			return findMedianOfMedians(medianVecs, 0, medianVecs.size());
		}
	}
Пример #3
0
	//The Dselect Algo  -> deterministic select algorithm - Median of medians
	// break A into groups of 5 sort each group with what ever wanted
	// C = the n/5 "middle elements"
	// p = Select (C, n/5 , n/10) recursevly computes median of C
	// Partition A around p
	// if j = i return p
	// if j < i return select ( first part of A, j-1 , i)
	// else if j  > i return select ( second part of A , n-j , i-j)
	void DselectAlgo(std::vector<int>& input, int left, int right)
	{

		//std::cout << "----------------------------" << std::endl;
		//std::cout << "LR: " << left << "|" << right << std::endl << std::endl;
		std::vector<int>::iterator bound;

		int median = findMedianOfMedians(input, left, right);

		//int indexPivot = partition_around_pivot_a(input, left, right, median);

		bound = std::partition(input.begin() + left, input.begin() + right, [median](int val){return val < median; });

		//for (int i = 0; i < input.size(); ++i)
		//{
		//	std::cout << input[i] << ", ";
		//}
		//std::cout << std::endl;

		//int boundIdx = left + indexPivot;
		int boundIdx = bound - input.begin();

		//std::cout << "m: " << median;
		//std::cout << " idx " << boundIdx << std::endl;

		// check if work is done
		if ((boundIdx - left) > 1) // left side
		{
			//std::cout << "left " << std::endl;
			//std::cout << "----------------------------" << std::endl << std::endl;
			DselectAlgo(input, left, boundIdx);
		}
		if ((right - boundIdx) > 1) // right side
		{
			//std::cout << "right " << std::endl;
			//std::cout << "----------------------------" << std::endl << std::endl;
			DselectAlgo(input, boundIdx, right);
		}

	}
Пример #4
0
/* Recursive engine (partial quicksort) */
void findFirstK(mwIndex left, mwIndex right) {
    
    mwIndex pivotIndex;

    if (right > left) {
        
#if (PIVOT==MEDIANMEDIANS)
        pivotIndex = findMedianOfMedians(left, right);
#elif (PIVOT==MEDIAN3)
        pivotIndex = findMedianThree(left, right);
#else /* MIDPOINT */
        pivotIndex = (left+right+1)/2;
#endif
        
        pivotIndex = partition(left, right, pivotIndex);
        if (pivotIndex > k)
            findFirstK(left, pivotIndex-1);
        else if (pivotIndex < k)
            findFirstK(pivotIndex+1, right);
    }
    
    return;
} /* findFirstK */