알고리즘 분석 및 실례 해석(一)-분치법
5199 단어 데이터 구조와 알고리즘
규모가 n인 문제에 대해 만약에 이 문제가 쉽게 해결될 수 있다면 직접 해결하고 그렇지 않으면 k개의 규모가 비교적 작은 자 문제로 분해한다. 이 자 문제들은 서로 독립적이고 원 문제의 형식과 같으며 귀속적으로 이 자 문제를 해결한 다음에 각 자 문제의 해를 합쳐서 원 문제의 해를 얻는다.이런 알고리즘 설계 전략을 분치 전략이라고 한다.
분치법은 각 층의 귀속에 세 가지 절차로 구성된다.
분치법에는 어떤 고전적인 예가 있습니까?그것은 정말 많다. 비교적 흔히 볼 수 있는 것은 아래에 일일이 열거하여 분석할 것이다.
이분법 찾기
이분법이 해결하는 기본적인 문제는 이미 알고 있는 n개의 서열에서 주어진 원소가 존재하는지 찾는 것이다.이분법의 기본 사상은 두 갈래로 나무를 찾는 구조에 쓰였다.
다음은 c++ 프로그램 코드입니다.
#include
#include
#include
#include
#include
int * rand_seq(int num)// num
{
int *tem=new int[num];
srand((unsigned)time(NULL));
for(int i=0;i(std::cout," "));
std::cout<<:endl int="" bin_search="" num="" key="" begin="0;" end="num-1;" while="" mid="(begin+end)/2;" if="" return="" else="" rec_bin_search="" null="" main="" argc="" char="" argv="" print_seq="" res="bin_search(data,20,data[2]);" std::cout="" success="" at=""/>
최대값과 최소값 찾기
문제 설명: n개의 서로 다른 원소의 집합에서 그것의 최대치와 최소치를 동시에 찾아낸다.
일반적인 역법으로 최악의 경우 비교 횟수는 2(n-1), 분치법 비교 횟수는 3n/2-2이다. 코드를 보면 다음과 같다.
#include
#include
#include
#include
#include
#include
int * rand_seq(int num)// num
{
int *tem=new int[num];
srand((unsigned)time(NULL));
for(int i=0;i(std::cout," "));
std::cout<<:endl void="" rec_maxmin="" if="" res_max="res_min=*begin;" else="">*end)?(res_max=*begin,res_min=*end):
(res_max=*end,res_min=*begin);
}else
{
int *mid=begin+(end-begin)/2;
int lmax=INT_MIN,rmax=INT_MIN,lmin=INT_MAX,rmin=INT_MAX;
rec_MaxMin(begin,mid,lmax,lmin);
rec_MaxMin(mid+1,end,rmax,rmin);
res_max=std::max(lmax,rmax);
res_min=std::min(lmin,rmin);
}
}
int main(int argc, char** argv)
{
int *data=rand_seq(20);
print_seq(data,20);
// ,INT_MAX INT_MIN limits.h
int max=INT_MIN;
int min=INT_MAX;
/* std::cout<
제k 소원소 문제 구하기
이 문제는 최대치의 최소값을 구하는 문제에서 나온 것이다. 문제 설명: n개의 서로 다른 원소의 집합에서 그의 k소값을 찾아낸다.이 문제를 선택문제라고도 부른다.
당1
만약 빠른 정렬에서의 구분 방법을 사용한다면, 주원을 기준으로 한 표를 좌우 두 개의 하위 표로 구분한다.원표의 길이를 n으로 하고 한 차례의 구분을 거쳐 두 개의 좌우 자표로 나눈다고 가정한다. 그 중에서 왼쪽 자표는 주원과 왼쪽 원소의 자표이고 그 길이는 p, 오른쪽 자표는 주원의 오른쪽 원소의 자표이다.그러면 만약에 k==p라면 주원은 제k소원소이다.하면, 만약, 만약...
다음 두 가지 사고방식의 코드:
#include
#include
#include
#include
#include
int * rand_seq(int num)// num
{
int *tem=new int[num];
srand((unsigned)time(NULL));
for(int i=0;i(std::cout," "));
std::cout<<:endl void="" adjust_heap="" key="" num="" if="" int="" left="2*key+1;" right="2*key+2;" min_index="(data[key]">data[left])?((rightdata[right])?right:left):((rightdata[right])?right:key);
if(min_index!=key)
{
std::swap(data[key],data[min_index]);
adjust_heap(data,min_index,num);
}
}
}
void build_heap(int *data,int num)
{
int max_index=(num-1)/2;
for(int i=max_index;i>=0;i--)
adjust_heap(data,i,num);
}
int k_min_heap(int *data,int num,int k)
{
build_heap(data,num);
for(int i=1;item) --right;
while((left
병합 정렬 & 빠른 정렬
이 두 가지 정렬 방법은 모두 정렬을 분리하는 대표적인 예이다. 특히 정렬을 병합하는 것은 분해, 정렬, 합병이다.
이 두 가지 방법에 대한 상세한 소개는 나의 또 다른 논문인 을 참고한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
두 갈래 나무의 깊이가 두루 다니다텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.