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;
}
运行结果:
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;
}
#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;
}
#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;
}
#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;
}
#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;
}
#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;
}