二 分 法
1.典型二分法 : 分金子,找出最重的 和最轻的
#include<iostream>
using
namespace
std;
float
a[100];
void
maxmin(
int
i,
int
j,
float
&fmax,
float
&fmin)
{
int
mid;
float
lmax,lmin,rmax,rmin;
if
(i==j)
{
fmax=a[i];fmin=a[i];
}
else
if
(i==j-1)
{
if
(a[i]>a[j]){fmax=a[i];fmin=a[j];}
else
{fmax=a[j];fmin=a[i];}
}
else
{
mid=(i+j)/2;
maxmin(i,mid,lmax,lmin);
maxmin(mid+1,j,rmax,rmin);
if
(lmax>rmax)fmax=lmax;
else
fmax=rmax;
if
(lmin<rmin) fmin=lmin;
else
fmin=rmin;
}
}
int
main()
{
int
n,i;
float
max,min;
cin>>n;
for
(i=0;i<n;i++)
cin>>a[i];
maxmin(0,n-1,max,min);
cout<<max<<
" "
<<min<<endl;
return
0;
}
——------------------------------------------------------------------------------
3.二分法不独立情况
求数列的最大子段和(处理公共子段)
#include<iostream>
#include<fstream>
using
namespace
std;
int
max_sub_sum(
int
a[],
int
left,
int
right)
{
int
left_sum,right_sum,lefts,rights,s1,s2,mid,i;
if
(left==right)
{
if
(a[left]>0)
return
a[left];
else
return
0;
}
else
{
mid=(left+right)/2;
left_sum=max_sub_sum(a,left,mid);
right_sum=max_sub_sum(a,mid+1,right);
lefts=a[mid]; s1=a[mid];
for
(i=mid-1;i>=left;i--)
{
lefts=lefts+a[i];
if
(lefts>s1)
s1=lefts;
}
rights=a[mid+1];s2=a[mid+1];
for
(i=mid+2;i<=right;i++)
{
rights=rights+a[i];
if
(rights>s2)
s2=rights;
}
if
(left_sum>right_sum&&left_sum>(s1+s2))
return
left_sum;
if
(right_sum>(s1+s2))
return
right_sum;
return
(s1+s2);
}
}
int
main()
{
int
a[50];
int
i,n;
ifstream cin(
"a.txt"
);
cin>>n;
for
(i=0;i<n;i++)
{
cin>>a[i];
}
cout<< max_sub_sum(a,0,n-1)<<endl;
return
0;
}
----------------------------------------------------------------------------------------------------------------------------
非等分分治
求一组数组中,第二小的数 (分成求 每组数中的前两个小的数,最后一次的返回后在4个数中,可以找到第二小的数)
#include<iostream>
#include<fstream>
using
namespace
std;
int
a[50];
void
two(
int
i,
int
j,
float
&fmin1,
float
&fmin2)
{
float
mid,lmin1,lmin2,rmin1,rmin2;
if
(i==j)
{
fmin2=a[i];
fmin1=a[i];
return
;
}
else
if
(i==j-1)
{
if
(a[i]>a[j])
{
fmin1=a[j];
fmin2=a[i];
}
else
{
fmin1=a[i];
fmin2=a[j];
}
return
;
}
else
{
mid=(i+j)/2;
two(i,mid,lmin1,lmin2);
two(mid+1,j,rmin1,rmin2);
if
(lmin1>rmin1)
{
if
(lmin1>rmin2)
{
fmin1=rmin1;
fmin2=rmin2;
}
else
{
fmin1=rmin1;
fmin2=lmin1;
}
}
else
{
if
(rmin1<lmin2)
{
fmin1=lmin1;
fmin2=rmin1;
}
else
{
fmin1=lmin1;
fmin2=lmin2;
}
}
}
}
int
main()
{
int
n;
float
fmin1,fmin2;
ifstream cin(
"a.txt"
);
cin>>n;
int
i;
for
(i=0;i<n;i++)
{
cin>>a[i];
}
two(0,n-1,fmin1,fmin2);
cout<<fmin2<<endl;
return
0;
}
----------------------------------------------------------
----------------------------------------------------------
在一个一维数组中,找到第k个小的数
---------------------------------------------------------------------
===========================================================================================
折半查找 排序法(c#)
if(listBox1.Items .Count ==0)
foundPostion =0;
else
{
endPosition =listBox1 .Items .Count -1;
while(!found && startPosition <= endPosition )
{
midPosition =(startPosition+endPosition)/2;
if(double_Array [midPosition ].Equals(double.Parse (s)) )
{
found=true;
foundPostion =midPosition ;
}
else
{
if(double_Array[midPosition ].CompareTo (double.Parse (s))>0)
endPosition =midPosition -1;
else
startPosition =midPosition +1;
}
}
if (!found)
foundPostion = startPosition;
}
listBox1.Items.Insert(foundPostion, double.Parse(s));