基本的算法设计技术——减治法

1.两个序列的中位数
完整代码:

#include<iostream>
#include <math.h>
using namespace std;
int SearchMid(int A[],int B[],int n)
{
	int s1=0,e1=n-1,s2=0,e2=n-1;
	int mid1,mid2;
	while((s1<e1)&&(s2<e2))	
	{
		mid1=(s1+e1)/2;
		mid2=(s2+e2)/2;
		if(A[mid1]==B[mid2])
			return A[mid1];
		if(A[mid1]<B[mid2])
		{
			if((s1+e1)%2==0) 
				s1=mid1;
			else s1=mid1+1;
			e2=mid2;
		}
		else
		{
			if((s2+e2)%2==0) 
				s2=mid2;
			else s2=mid2+1;
			e1=mid1;
		}
	}
	if(A[s1]<B[s2])
		return A[s1];
	else
		return B[s2];
} 
int main()
{
	int A[]={1,2,3,5,7};
	int B[]={2,4,6,8,10};
	int mid=SearchMid(A,B,5);
	cout<<"两个序列的中位数是:"<<mid<<endl;
	return 0;
}

运行结果:
基本的算法设计技术——减治法_第1张图片
2.查找问题中的减治法
1>折半查找
完整代码:

#include<iostream>
using namespace std;
int BinSearch(int r[ ],int n,int k)
{
	int low=0;
	int high=n-1;
	int mid;
	while(low<=high)
	{
		mid=(low+high)/2;
		if(k<r[mid])
			high=mid-1;
		else if(k>r[mid])
			low=mid+1;
		else return mid;
	}	
	return 0;
}
int main()
{
	int r[]={7, 14, 18, 21, 23, 29, 31, 35, 38};
	int i=BinSearch(r,9,18);
	cout<<"在数组中的下标是:"<<i<<endl;
	return 0;
}

运行结果:
基本的算法设计技术——减治法_第2张图片
2>二叉查找树

#include<iostream>
using namespace std;
typedef struct BiNode
{
	int data;
	BiNode *lchild,*rchild;	
}BiNode;

BiNode *InsertBST(BiNode *root,int data)
{
	if(root==NULL)
	{
		root=new BiNode; 
		root->data=data;
		root->lchild=root->rchild=NULL;
		return root; 
	}
	if(data<=root->data)
		root->lchild=InsertBST(root->lchild,data);
	else
		root->rchild=InsertBST(root->rchild,data);
	return root;
} 

BiNode *createBST(int a[ ],int n)//将无序序列a[n]建立二叉查找树 
{
	BiNode *T=NULL;
	for(int i=0;i<n;i++)
		T=InsertBST(T,a[i]);
	return T;
}

BiNode *SearchBST(BiNode *root,int k)
{
	if(root==NULL)
		return NULL;
	else if(k==root->data)
		return root;
	else if(k<root->data)
		return SearchBST(root->lchild,k);
	else
		return SearchBST(root->rchild,k);	
}

int main()
{
	BiNode *root, *t;
	int a[]={55,42,10,70,63,58,83,67,90,45};
	root=createBST(a,10);
    t=SearchBST(root,58);
	if(t != NULL)
		cout<<"查找成功"<<endl;
	else
		cout<<"查找失败"<<endl;
	return 0;
}

运行结果:
基本的算法设计技术——减治法_第3张图片
3>选择问题
完整代码:

#include<iostream>
using namespace std;
int Partition(int r[ ],int first,int end)//快速排序 
{
	int i=first,j=end;
	while(i<j)
	{
		while(i<j&&r[i]<=r[j])
			j--;//右侧扫描
		if(i<j)
		{
			int temp=r[i];r[i]=r[j];r[j]=temp;	
			i++;
		}
		while(i<j&&r[i]<=r[j])
			i++;
		if(i<j)
		{
			int temp=r[i];r[i]=r[j];r[j]=temp;	
			j--;
		}	
	}
	return i;	
}
int SelectMinK(int r[ ],int low,int high,int k)
{
	int s;
	s=Partition(r,low,high);
	if(s==k)
		return r[s];
	if(s>k)
		return SelectMinK(r,low,s-1,k);
	else
		return SelectMinK(r,s+1,high,k);
} 

int main()
{
	int r[]={5,3,8,1,10,6,9,12,17};
	int k = 3;
	int x = SelectMinK(r,0,8,k-1);
    cout<<"第"<<k<<"小的元素是"<<x<<endl;
	return 0;
} 

运行结果:
基本的算法设计技术——减治法_第4张图片
3.排序问题中的减治法
1>插入排序

#include<iostream>
using namespace std;

void InsertSort(int r[ ],int n)
{
	int i,j;
	for(int i=2;i<=n;i++)
	{
		r[0]=r[i];//哨兵 
		for(j=i-1;r[0]<r[j];j--)//寻找待插入位置 
			r[j+1]=r[j];//记录后移 
		r[j+1]=r[0];
	}
}

int main()
{
	int r[]={0,12,15,9,20,10,6};
	InsertSort(r,6);
	for(int i=0;i<7;i++)
		cout<<r[i]<<"  ";
	return 0;
}

运行结果:
在这里插入图片描述
2>堆排序

#include<iostream>
using namespace std;
void SiftHeap(int r[ ],int k,int n)
{
	int i,j,temp;
	i=k;j=2*i+1;//i为要筛结点,j为i的左孩子 
	while(j<n)//筛选还没有进行到叶子 
	{
		if(j<n-1&&r[j]<r[j+1])//比较i的左右孩子,j为较大者 
			j++;
		if(r[i]>r[j])//根结点已经大于左右孩子中的较大者 
			break;
		else
		{
			temp=r[i];r[i]=r[j];r[j]=temp;//将被筛结点与结点j交换 
			i=j;j=2*i+1;//被筛结点换为原来结点j 
		}	
	}	
} 
void HeapSort(int r[],int n)
{
	int i,temp;
	for(i=(n-1)/2;i>=0;i--)//初始建堆,最后一个分支的下标是(n-1)/2,此时已经是大根堆。 
		SiftHeap(r,i,n);
	for(i=1;i<=n-1;i++)//重复执行移走堆顶及重建堆操作,将原大根堆的堆顶与最后元素交换,之后元素减少一个
//(每次最后一个最大的元素存入数组),再重建堆。从数组中最后一个元素往前依次存最大的元素到最小元素,使数组中元素有序。 
	{
		temp=r[0];r[0]=r[n-i];r[n-i]=temp;
		SiftHeap(r,0,n-i); 
	}
}

int main()
{
	int r[]={47,33,35,2,18,71,26,13};
	HeapSort(r,8);
	for(int i=0;i<8;i++)
		cout<<r[i]<<"  ";
	return 0;
}

运行结果:
在这里插入图片描述
4.组合问题中的减治法
1>淘汰赛冠军问题
在这里插入图片描述
完整代码:

#include<iostream>
using namespace std;
int Comp(char a,char b)
{
	if(a>b) 
		return 1;
	else 
		return 0;
}
//函数Comp模拟两位选手mem1和mem2的比赛,若mem1获胜则Comp返回1,否则返回0 
char Game(char r[ ],int n)
{
	int i=n;
	while(i>1)
	{
		i=i/2;
		for(int j=0;j<i;j++)
		{
			if(Comp(r[j+i],r[j]))
				r[j]=r[j+i];
		}	
	}
	return r[0];
} 

int main()
{
	char r[]="AFGBEHCD";
	char c=Game(r,8);
	cout<<"最后的冠军是:"<<c<<endl;
	return 0;
}

运行结果:
基本的算法设计技术——减治法_第5张图片
2>假币问题
完整代码:

#include<iostream>
using namespace std;
const int N=8;
int a[N]={2,2,1,2,2,2,2,2};
int Coin(int low,int high,int n)
{
	int i,num1,num2,num3;
	int add1=0,add2=0;
	if(n==1)
		return low+1;
	if(n%3==0)
		num1=num2=num3=n/3;	
	else
	{
		num1=num2=n/3+1;
		num3=n-num1-num2;	
	}
	for(i=0;i<num1;i++)
		add1+=a[low+i];
	for(i=num1;i<num1+num2;i++)
		add2+=a[low+i];
	if(add1<add2)
		return Coin(low,low+num1-1,num1);
	else if(add1>add2)
		return Coin(low+num1,low+num1+num2-1,num2);
	else
		return Coin(low+num1+num2,high,num3);	
} 
int main()
{
	int i=Coin(0,7,8);
	cout<<"假币是第"<<i<<"个"<<endl;
	return 0;
}

运行结果:
基本的算法设计技术——减治法_第6张图片

你可能感兴趣的:(基本的算法设计技术——减治法)