编程之美系列之寻找最大的K个数

所有代码均已测试,后续部分待更新。

头文件如下:

 /*
 *  ********************************************
 *				BeautyOfProgramming
 *  ********************************************
 */
//
//
//

#include "Common.h"

// 编程之美代码的测试函数
void BeautyOfProgrammingCppTest();

/*********************************
 * 面试题2.5:寻找最大的K个数 P139
 *********************************/

template<typename T>
class slctKMax
{
public:
	slctKMax( vector<T> v , int k );
	~slctKMax();
	void sln1();// 先排序在选择,或者直接用部分排序算法(选择排序或者交换排序),即把前K个数排序出来
	void sln2();// 引用快速排序的思想
	void sln2_partionSort( int strt, int bgin ,bool sort);// 快速排序
	void sln3();// 引用二分搜索的思想的思想
	void sln4();// 引用堆排序的思想
	void sln5();// 改进计数排序和基数排序
	void printslctKMax();
private:
	vector<T> v;
	int k;
	
};
// sln1.: 询问面试官K的大小,并依此在快速偏序、堆排序与选择排序或交换排序中选择

// sln2.: 回忆一下快速排序,快速排序都是将待排数据分为两组。递归下去可以把问题分为更小的问题,平均时间复杂度更小。
// 通过快速排序找最大或者最小的K个数,很方便。其中并没有对这K个数进行排序。所以其效率比较高。
// sln3.: 回忆一下快速排序,快速排序都是将待排数据分为两组。

// sln4.: 回忆一下快速排序,快速排序都是将待排数据分为两组。

// sln5.: 回忆一下快速排序,快速排序都是将待排数据分为两组。


// slctKMaxTest
void slctKMaxTest( );

/*******************************
 *面试题2.6:精确表达浮点数 P147
 *******************************/

template<typename T>
class floatDouble
{
public:
	floatDouble( vector<T> v );
	~floatDouble();
	void sln1();
	void sln2();
	void sln3();
	void sln4();
	void sln5();
	void printfloatDouble();
private:
	vector<T> v;
	
};

// floatDoubleTest
void sfloatDoubleTest( );


/*******************************
 *面试题2.7:最大公约数问题 P151
 *******************************/

template<typename T>
class gcd
{
public:
	gcd( vector<T> v );
	~gcd();
	void sln1();
	void sln2_partionSort();
	void sln2();
	void sln3();
	void sln4();
	void sln5();
	void printgcd();
private:
	vector<T> v;
	
};

// gcdTest
void gcdTest( );

CPP文件如下:

#include "BeautyOfProgramming.h"


void BeautyOfProgrammingCppTest()
{
	// 2.5:寻找最大的K个数
	slctKMaxTest( );



	return;
}

// 2.5:寻找最大的K个数
template<typename T>
void slctKMax<T>::sln1( )
{
	return;
}

template<typename T>
void slctKMax<T>::sln2_partionSort( int strt, int end ,bool sort) // i,j分别标示当前需要进行就位的数组区段的始末位置
{ 
	if( strt >= end ) return;	
	int key = strt; // 标示key的位置
	int i = strt;
	int j = end;
	for( ; i != j;  ){ 
			while( v[j] >= v[key] && i < j ) j--;
			while( v[i] <= v[key] && i < j ) i++; 
			if( i != j ){ 				
				::swap<T>(v[i],v[j]);
			}			
	} 
	if( i == j )
	{  // key就位
		if(  i != key  ){ // 需要交换
			::swap<T>( v[key], v[i] ); 	 
		}
		if( 1 == sort ){
			sln2_partionSort(strt, i-1 ,1);
			sln2_partionSort( i+1, end ,1);
		}
		else
		{
			if( i+1 > k ){
				sln2_partionSort(strt, i-1 ,0 );
			}
			else if( i+1 < k ){
				sln2_partionSort( i+1, end ,0 );
			}
			else if( i+1 == k )
			{
				for( vector<T>::iterator itrtr = v.begin(); itrtr != v.begin()+k; itrtr++ )
					cout<<*itrtr<<" ";
				cout<<endl;
			}
		}		
	}
	return;
}
template<typename T>
void slctKMax<T>::sln2( ) // 核心就是第K个合适位置上那个元素找出来,放在这个位置上,那么就找到了前面几个数。
{
	if( k < 1 ) return;	
	clock_t begin, end;
	begin = clock();
	sln2_partionSort(0, v.size()-1,0);
	end = clock();
	cout<<"the run time of sln2 is : "<<end-begin<<" ms"<<endl;
	cout<<endl<<"-----sln2 end--------"<<endl;
	sln2_partionSort(0, v.size()-1,1);
	return;
}

template<typename T>
void slctKMax<T>::sln3( )
{
	return;
}

template<typename T>
void slctKMax<T>::sln4( )
{
	return;
}

template<typename T>
void slctKMax<T>::sln5( )
{
	return;
}

template<typename T>
slctKMax<T>::slctKMax( vector<T> v , int k )
{
	(*this).v = v;
	(*this).k = k;
}

template<typename T>
slctKMax<T>::~slctKMax( ){ }

template<typename T>
void slctKMax<T>::printslctKMax( )
{
	for(int  i = 0; i < v.size(); i++ )
		cout<<v[i]<<" ";
	cout<<endl<<k<<endl;
	return;
}

// slctKMaxTest
void slctKMaxTest( )
{
	clock_t begin, end;
	vector<int> v;
	v.push_back(11);
	v.push_back(123);
	v.push_back(2);
	v.push_back(1);
	v.push_back(4);
	v.push_back(56);
	v.push_back(44);
	v.push_back(45);
	v.push_back(65);
	v.push_back(8);
	v.push_back(8);
	//for( int i = 0; i < 10000000; i++ )
		//v.push_back(rand()%10000000 + i);	
	slctKMax<int> test(v, 8);
	test.printslctKMax();	
	//begin = clock();	
	test.sln2();
	//end = clock();
	//cout<<"the time is : "<<end-begin<<" ms"<<endl;
	test.printslctKMax();
	return;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值