(2) Divide & Conquer
24367 ワード
1. Merge Sort
1. 정렬되지 않은 리스트를 절반으로 잘라 두 개의 리스트로 나눈다.
2. 생성된 두개의 리스트를 Merge Sort 알고리즘을 재귀 호출하여 정렬한다.
3. 정렬된 두개의 리스트를 다시 하나의 정렬된 리스트로 Merge한다.
int arr[MAX_N + 10];
int sorted[MAX_N + 10];
void merge(int left, int mid, int right)
{
int i, j, k;
i = left;
j = mid + 1;
k = left;
while (i <= mid && j <= right)
{
if (arr[i] <= arr[j])
sorted[k++] = arr[i++];
else
sorted[k++] = arr[j++];
}
if (i > mid) // 남아있는 값들 일괄 복사
{
while (j <= right)
sorted[k++] = arr[j++];
}
else
{
while (i <= mid)
sorted[k++] = arr[i++];
}
for (i = left; i <= right; ++i) // 배열 복사
arr[i] = sorted[i];
}
void merge_sort(int left, int right)
{
int mid;
if (left < right)
{
mid = (left + right) / 2;
merge_sort(left, mid);
merge_sort(mid + 1, right);
merge(left, mid, right);
}
}
2. Quick Sort
1. 리스트 내에 임의의 원소를 선택하여 pivot이라 명합니다.
2. pivot을 기준으로 pivot보다 작은 원소는 좌측으로, pivot보다 큰 원소는 우측으로 이동합니다.
3. pivot을 제외하고 좌측 리스트와 우측 리스트를 Quick Sort 알고리즘을 재귀 호출하여 정렬합니다.
4. pivot으로 나눠진 리스트의 크기가 1이 될 때까지 반복합니다.
void quick_sort(int left, int right)
{
int start, end, pvt;
start = left;
end = right;
pvt = arr[(left + right) / 2];
if (left >= right)
return ;
while (start <= end)
{
while (arr[start] > pvt)
++start;
while(arr[end] < pvt)
--end;
if (start <= end)
{
arr[start] ^= arr[end];
arr[end] ^= arr[start]
arr[start] ^= arr[end];
++start;
--end;
}
}
quick_sort(left, end);
quick_sort(start, right);
}
3. Binary Search
二分探索の必要条件
int binary_search(int arr[], int start, int end, int target)
{
int mid;
while (start <= end)
{
mid = (start + end) / 2;
if (arr[mid] == target)
return (mid);
elseif (arr[mid] < target)
start = mid + 1;
else
end = mid - 1;
}
return (-1);
}
int main(void)
{
int arr[4] = {0, 1, 2, 3};
int ans;
ans = binary_search(arr, 0, 3, 2);
return (0);
}
int count_by_range(vector<int> &v, int left, int right)
{
vector<int>::iterator right_idx = upper_bound(v.begin(), v.end(), right);
vector<int>::iterator left_idx = lower_bound(v.begin(), v.end(), left);
return (right_idx - left_idx);
}
3-1. パラメータ検索:一般問題→決定問題
これは
下限→最小値を求める。
最小値がxであれば、x以上の値に対して条件を満たす.
int solve(void)
{
int start, end, mid, ans;
start = MIN;
end = MAX;
ans = mid = 0;
while (start <= end)
{
mid = (start + end) / 2;
if (verify(mid))
{
ans = mid;
end = mid - 1;
}
else
start = mid + 1;
}
return (ans);
}
Upper Bound→最大値を求めます。
最大値がxである場合、x以下の値については、いずれも条件を満たす.
int solve(void)
{
int start, end, mid, ans;
start = MIN;
end = MAX;
ans = mid = 0;
while (start <= end)
{
mid = (start + end) / 2;
if (verify(mid))
{
ans = mid;
start = mid + 1;
}
else
end = mid - 1;
}
return (ans);
}
[参照]パラメータ検索 [BOJ]白準2110ルータを取り付ける
Reference
この問題について((2) Divide & Conquer), 我々は、より多くの情報をここで見つけました https://velog.io/@24siefil/2-Divide-Conquerテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol