병합 정렬에 들어가기위한 첫 번째 시도로서 문자열에 대해 작동하는 다음 코드를 처리했습니다. 처리 할 목록보다 쉽기 때문입니다. 최적화의 가능성에 대해 위키 백과에 읽기재귀 알고리즘을 꼬리 재귀 알고리즘으로 바꾸려면 어떻게해야합니까?
class Program
{
static int iterations = 0;
static void Main(string[] args)
{
string test = "zvutsrqponmlihgfedcba";
test = MergeSort(test);
// test is sorted after 41 iterations
}
static string MergeSort(string input)
{
iterations++;
if (input.Length < 2)
return input;
int pivot = 0;
foreach (char c in input)
pivot += c;
pivot /= input.Length;
string left = "";
string right = "";
foreach (char c in input)
if (c <= (char)pivot)
left += c;
else
right += c;
return string.Concat(new string[] { MergeSort(left), MergeSort(right) });
}
}
나는 다음과 같은 힌트 "공간이 사용됩니다 (N 로그) O는, 배열의 작은 절반으로 첫 번째 재귀 최대 있는지 확인하고 재귀하는 꼬리 호출을 사용하려면 발견 다른쪽에. " 솔직히 이걸 내 사건에 적용하는 방법을 모르겠다. 재귀 및 계승에 관해 배울 때 IT 클래스의 꼬리 호출에 대한 막연한 기억이 있습니다. 그러나 위키 백과의 조언을 코드 조각에 적용하는 방법을 실제로 이해할 수 없습니다.
도움을 주시면 감사하겠습니다.
[C#은 마무리 호출 최적화를 지원하지 않습니다.] (@stackoverflow.com/questions/491376/why-doesnt-net-c-optimize-for-tail-call-recursion) –
@RobertHarvey Dangit , 나는 막 게시하려고했다. – cdhowie
@RobertHarvey : 음, 복잡합니다. C# 컴파일러가 꼬리 호출 명령어를 생성하지 않더라도 x64 지터는 일부 상황에서 테일 호출을 생성하지만이 중 하나가 아닙니다. 그러나이 질문은 꼬리 재귀 적으로 프로그램을 "수동으로"재 작성하는 것에 관한 것입니다. –