Algorithms: fast scheduling, one-time partition problem, nearest point pair, K-smallest

Keywords: less

I. A Division of Fast Row

#include <iostream>
#include <stack>
#include <queue>
using namespace std;

template<class Type>
int Partition(Type *arr,int left,int right)  
//A partition of the fast row, returning the subscript i, dividing the data into two parts with I
//Part is greater than i, part is less than i
{
	int i=left;
	int j=right;
	Type tmp=arr[left];
	while(i<j)
	{
		while(i<j && arr[j] > tmp)
		{
			--j;
			if(i<j) arr[i]=arr[j];
		}
		while(i<j && arr[i] < tmp)
		{
			++i;
			if(i<j) arr[j]=arr[i];
		}
	}
	arr[i]=tmp;
	return i;
}

2. Fast-scheduling recursive calls

template <typename Type>      // Fast-scheduling recursive calls
void PassQuick(Type *arr,int left,int right)
{
	if(left <right)
	{
		Type mid=Partition(arr,left,right);
		PassQuick(arr,left,mid-1);
	    PassQuick(Type *arr,mid+1,right);
	}
}

3. Fast-scheduling non-recursive calls

Quick-queued non-recursive calls can take two forms, stack and queue.

template<class Type>
void QuickSort(Type *ar,int n)
{
	SNicePassQuick(ar,0,n-1); //Use stack to make fast non recursive calls
	QNicePassQuick(ar,0,n-1); //Quick-queued non-recursive calls with queues
}

  1. Utilization stack
template <class Type>            //Using stack for fast-scheduling non-recursive calls
void SPassQuick(Type *arr,int left,int right)
{
	if(left >= right) return ;
	stack<int> s;
	s.push(left);
	s.push(right);
	while(! s.empty())
	{
		right=s.top();s.pop();
		left =s.top();s.pop();
		Type mid=Partition(arr,left,right);
		if(left < mid-1)
		{
			s.push(left);
			s.push(mid -1);
		}
		if(mid+1 < right)
		{
			s.push(mid +1);
			s.push(right);
		}
	}
}
  1. Using queues
template<class Type>     //Quick-queued non-recursive calls with queues
void QPassQuick(Type *arr,int left,int right)
{
	if(left >=right) return ;
	queue<int> q;
	q.push(left);
	q.push(right);
	while(! s.empty() )
	{
		left =q.front();   q.pop();
		right=q.front();   q.pop();
		int mid = Partition(ar,left,right);
		if(left < mid-1)
		{
			q.push(left);
			q.push(mid-1);
		}
		if(mid+1 < right)
		{
			q.push(mid+1);
			q.push(right);
		}
	}
}

4. Optimizing the Random Number Method of Fast Row and the Three-in-One Method

  1. Random number method
template<class Type>          //Random number method
int RandPartition(Type *ar,int left,int right)
{
	srand(time(NULL));
	int pos = rand() %(right - left + 1) + left;
	swap(ar[left],ar[pos]);
	return Partition(ar,left,right);
}

  1. Three in the middle
template<class Type>         //Three in the middle
int MidPartition(Type *ar,int left,int right)
{   // 23 89 45 
	int mid = (right - left + 1)/2 + left;
	//ar[left] , ar[mid] , ar[right];
	if(ar[mid] > ar[left] && ar[mid] < ar[right])
	{
		swap(ar[mid],ar[left]);
	}else if(ar[right] > ar[mid] && ar[right] < ar[left])
	{
		swap(ar[right],ar[left]);
	}

	return Partition(ar,left,right);
}

There is a serious error in this three-digit middle method: two if statements cannot determine the sequence of three numbers. The following methods can be considered for optimization:

  • Define a structure:
struct MidNode
{
      Type data;
      int indax;
}
  • Three median functions in STL library, Mid [3]={X, X, X} - --> mid [1]

Fifth, quick row division: to find the decimal number

int Select_K_Min (int *ar,int n,int k)
{
	if(ar == NULL || n < 1 || k<1 || k > n)
		return -1;
	else
		return Select_K(ar,0,n-1,k);
}

int Select_K(int *ar,int left,int right,int k)
{
	if(left == right && k == 1) return ar[left];

	int pos = Partition(ar,left,right);
	int j = pos - left + 1;
	if(k <= j) return Select_K(ar,left,pos,k);
	else return Select_K(ar,pos+1,right,k - j);
}

6. One-time division of fast scheduling: the closest point-to-point problem

int CPari(int *ar,int n)
{
	if(ar == NULL || n < 1) return INT_MAX;
	else 
		return cPari(ar,0,n-1);
}


int cPari(int *ar,int left,int right)
{
	if(right - left <= 0) return INT_MAX;
	int k = (right - left + 1)/2;
	int pos = left + k - 1;
	Select_K(ar,left,right,k);// 0 1 2 3 4  // 5 6 7 8 9

	int d1 = CPari(ar,left,pos); //s1;
	int d2 = CPari(ar,pos+1,right); //s2;
	int maxs1 = MaxS1(ar,left,pos); //
	int mins2 = MinS2(ar,pos+1,right);
	return min(min(d1,d2),mins2 - maxs1);
}

int  MaxS1(int *ar,int left,int right)
{
	return ar[right];
}
int  MinS2(int *ar,int left,int right)
{
	int tmp = ar[left];
	for(int i = left+1;i<=right;++i)
	{
		if(tmp > ar[i])
		{
			tmp = ar[i];
		}
	}
	return tmp;
}

int main()
{
	int ar[]={56,67,12,23,90,85,45,78,34,100,20,14,55,23};
	int n = sizeof(ar)/sizeof(ar[0]);

	int minlen = CPari(ar,n);
	cout<<minlen<<endl;
	cout<<endl;

	return 0;
}


Posted by ready2drum on Thu, 03 Oct 2019 13:07:53 -0700