分治法--算法考试

分治法

    • 快速排序
    • 归并排序
    • 查找最大值和次大值问题
    • 折半查找
    • 2019 年女排世界杯

快速排序

#include 
 /**
  *分治法
  *快速排序
  **/ 
using namespace std;
//交换函数 
void swap(int*a,int*b)
{
	int t;
	t=*a;
	*a=*b;
	*b=t;	
}
//快速排序函数  选取任意一个数,使得左边的数都小于这个数,右边的数都大于这个数
//继续重复上述操作,直到递归全部完成  
void QucikSort(int*element,int left,int right)
{
	//递归终结条件 ,当左边大于等于右边时退出函数 
	if(left>=right)
	 return;
	//i赋值为第一个数 
	int i=left;
	//j赋值为最后一个数 
	int j=right;
	//k任意取一个数(一般为第一个) 
	int k=element[i]; 
	while(i<j)
	{
		if(j>i&&element[j]>=k)  //如果date[j]大于k j-- 
			j--;
		swap(element[i],element[j]);//if不满足后执行交换 
		if(i<j&&element[i]<=k) //如果 date[i]小于k i++ 
			i++;
		swap(element[i],element[j]);//if不满足执行交换 
	}
	QucikSort(element,left,i-1);//左边继续执行相同操作 
	QucikSort(element,i+1,right);//右边继续执行相同操作 
} 
void Output(int*element,int length)
{
	for(int i=0;i<length;i++)
	cout<<element[i]<<",";
}
int main(int argc, char** argv) {
	//测试 
	int a[]={1,2,3,9,5,6,0}; 
	QucikSort(a,0,6); 
	//输出 
	Output(a,7); 
	return 0;
}

归并排序

#include 
/**
  *分治法 
  *归并排序排序
**/
using namespace std; 
//合并左右两半为一个新的有序数组,并拷贝到原数组 
void Merge(int*element,int left,int m,int right,int*newelement)
{
	int L=left;
	int R=m+1;
	int pos=0;
	//合并左右两半有序数组依次放入新数组 
	while(L<=m&&R<=right)
	{
		if(element[L]<element[R])
		newdate[pos++]=element[L++];	
		else
		newdate[pos++]=element[R++];
	}
	//防止左边或者右边多出的数未加入到新数组
	while(L<=m)
	newelement[pos++]=element[L++];
	while(R<=right) 
	newelement[pos++]=element[R++];
	
	//拷贝回原数组 
	for(int i=0;i<right-left+1;i++)
	element[left+i]=newelement[i]; 
	
}
//归并排序函数  
//思路:  1.把前一半排序  2.把后一半排序  3.把前后两半归并到一个新有序数组,然后拷贝回原数组 
void MergeSort(int*element,int left,int right,int*newelement)
{
	//变量m存放数组长度的中间值 
	int m;
	//递归终止条件  
	if(left>=right)
		return; 
	//通过此计算方式代替(right+left)/2获取中间值 (此计算方式更安全) 
	m=left+(right-left)/2;
	//左右递归 
	MergeSort(element,left,m,newelement);
	MergeSort(element,m+1,right,newelement);
	//并
	Merge(element,left,m,right,newelement); 
} 
void Output(int*element,int length)
{
	for(int i=0;i<length;i++)
	cout<<element[i]<<",";
}
int main(int argc, char** argv) {
	//测试 
	int a[]={1,2,3,9,5,6,0}; 
	int*b=new int[sizeof(a)/4];
	MergeSort(a,0,6,b); 
	//输出 
	Output(a,7); 
	return 0;
}

查找最大值和次大值问题

#include 
#include 
/**
  *分治法 
  *最大值和次大值 
**/
using namespace std; 
void Solve(int*date,int& max1,int& max2,int low,int height)
{
	//只有一个数的情况 最大值为这个数,次大值为负无穷 
	if(low==height)
	{
		max1=date[low];
		max2="负无穷"; 
	} 
	//两个数的情况  最大值为两个数中最大的一个,次大值为两个数中最小的一个 
	else if(height-low==1)
	{
		max1=max(date[low],date[height]);//最大值 
		max2=min(date[low],date[height]);//次大值 
	}
	//两个数以上的情况  分为左边右边递归重复上述代码
	else
	{
		int mid=low+(height-low)/2;
		int lmax1,lmax2;
		Solve(date,lmax1,lmax2,low,mid); //求左边的最大值和次大值 
		int hmax1,hmax2;
		Solve(date,hmax1,hmax2,mid+1,height); //右边的最大值和次大值 
		
		if(lmax1>hmax1)
		{
			max1=lmax1;  //最大值赋值为lmax1 
			max2=max(lmax2,hmax1); //次大值在lmax2和hmax1里面求得最大值 
		}
		else
		{
			max1=hmax1;//最大值赋值为hmax1 
			max2=max(hmax2,lmax1);//次大值在hmax,lmax1里面求得最大值 
		}
	}
} 
void Output(int& max1,int& max2)
{
	cout<<"最大值:"<<max1<<"次大值:"<<max2;
}
int main(int argc, char** argv) {
	//测试 
	int a[]={1,2,3,9,5,6,0}; 
	int max1,max2;
	Solve(a,max1,max2,0,6);
	//输出 
	Output(max1,max2); 
	return 0;
}

折半查找

#include 
/**
  *分治法 
  *折半查找 
**/
using namespace std; 
int BinSearch(int*date,int left,int right,int D)
{	
	
	int mid;
				//若超出范围则返回-1 表示未找到 
	if(left>=right)
		return -1; 
				//求中间值 代替(left+right)/2方式 防止溢出 
	mid=left+(right-left)/2;
				//目标值大于中间值 则说明左边整体小于目标值 此时left移到mid+1 
	if(D>date[mid])
		BinSearch(date,mid+1,right,D);
				// 目标值小于中间值 则说明右边整体大于目标值 此时right移到mid-1 
	else if(D<date[mid])
		BinSearch(date,left,mid-1,D);
				//若找到返回目标值所在位置 
	else
	 	return mid;
} 
int main(int argc, char** argv) {
	//测试 
	int a[]={1,2,3,4,5,6,7}; 
	int lo=BinSearch(a,0,6,4);
	//输出 
	cout<<lo; //位置为3 
	return 0;
}

2019 年女排世界杯

2019 年女排世界杯,一共 12 个队伍进行比赛,比赛形式是:单循环赛制。也就是每个队伍之间进行有且仅有一场比赛,编写程序,输入 k 个队伍,输出对应的对阵表
例如 k 等于 4,表示 4 个队伍。单循环赛的赛程如下。

队伍 第一天对手 第二天对手 第三天对手
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
有时间再做。。。。

你可能感兴趣的:(分治法--算法考试)