1. 程式人生 > >分治策略(最差情況下查詢為線性時間演算法)

分治策略(最差情況下查詢為線性時間演算法)

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

/*********************************************************************** 
Input:a[]: 待排陣列序列 l:待排區間左下標,r:待排區間右下標 
Output:
Description: 氣泡排序
Return:  
Others:
************************************************************************/
template <class T>
void BubbleSort(T a[], int l ,int r)
{
	T tmp = a[l];   //臨時變數,交換使用
	for(int i=l; i<r; ++i)
	{
		for(int j=i+1; j < r; ++j)
		{
			if(a[i] > a[j])
			{
				tmp = a[i];
				a[i] = a[j];
				a[j] = tmp;
			}
		}
	}
}

/*********************************************************************** 
Input:a[]:待排陣列序列 l:待排區間左下標,r:待排區間右下標 
				  x 樞紐元素
Output:
Description:將陣列化分成 a[... x ...]。x左邊的元素都小於x,右邊的
                  元素都大於x。 
Return: 排序後樞紐元素的下標 
Others:
************************************************************************/
template <class Type>
int Partition(Type a[], int l, int r, Type x)
{
	int i = l;	//樞紐元素的索引號
	int j = r;	//a[]序列右邊界索引號
	while(i < j)
	{
		//從序列最右邊開始查詢,找到一個小於a[l]的為止;
		while (a[j] >= x && i < j) --j;
		if(i < j)
		{
			a[i] = a[j];
			i++;
		} 
		//從a[l]後面元素開始查詢,找到一個比a[l]大的為止; 
		while (a[i] < x && i < j) ++i; 
		if (i < j)
		{
			a[j] = a[i];
			j--;
		}
	}
	a[i] = x; //將a[i]的值寫回
	return i; //返回分割點的索引
} 


/*********************************************************************** 
Input:a[]: 待排陣列序列 l:待排區間左下標,r:待排區間右下標 
Output:
Description: 將陣列序列的第一個元素作為樞紐元素x,將陣列化分成 
             a[... x ...]。x左邊的元素都小於x,右邊的元素都大於x。 
Return:  
Others:
************************************************************************/
template <class T>
T Select(T a[], int l, int r, int k)
{
	//T tmp = a[l];  //初始化賦值任意元素
	if(r - l < 75)
	{
		BubbleSort(a, l, r);
		return a[l + k - 1];
	}
	for(int i=0; i<=(r-l-4)/5; ++i)
	{
		//將a[l+5*i] - a[l + 5*i + 4]的第3小元素與a[l+i]交換位置;
		BubbleSort(a, l+5*i, l+5*i + 5);
		
		tmp[i] = a[l + 5*i + 2];
		//a[l + i] = a[l + 5*i + 2];   //因為上面是已序的,所以可以很好的交換
		//a[l + 5*i + 2] = tmp;        //5個元素已經是排序了的
	}
	//找到中位數的中位數,r-l-4
	T x = Select(tmp, l, (r-l-4)/5, (r-l-4)/10);
	int i = Partition(a, l, r, x);
	int j = i - l + 1;
	
	if(k <= j)
		return Select(a, l, i, k);
	else
		return Select(a, i+1, r, k-j);
}


int tmp[25] = {0};

int main()
{
	int b[100] = {0};
	int a[100] = {0};
	//產生原序列
	srand((unsigned)time(NULL));
	cout << "The src array is: " << endl;
	for(int i=0; i<10; ++i)
	{
		for(int j=0; j<10; ++j)
		{
			b[i*10 + j] = rand()%100;
			cout<< b[i*10 + j] << '\t';
		}
		cout << endl;
	}
	cout << endl;
	
	memcpy(a, b, sizeof(a));
	BubbleSort(a, 0, 100);
	cout << "The src sorted array is: " << endl;
	for(int i=0; i<10; ++i)
	{
		for(int j=0; j<10; ++j)
		{
			cout<< a[i*10 + j] << '\t';
		}
		cout << endl;
	}
	cout << endl << endl;
	
	int tmpt = Select(b,0,100,15);
	cout<<"The 15 Min Element is : " << tmpt << endl;
	
	//氣泡排序
	BubbleSort(b, 0, 100);
	cout << "After finding,  array is: " << endl;
	for(int i=0; i<10; ++i)
	{
		for(int j=0; j<10; ++j)
		{
			cout<< b[i*10 + j] << '\t';
		}
		cout << endl;
	}
	cout << endl;
	
	return 0;
}

執行結果: