'재귀'를 이용한 정렬을 어떻게 구현해야 할까요...?

okkdy0628 Reply 3 years 46 weeks ago
배열의 원소가 하나가 될 때까지 무한히 쪼개고 합치고 하려면 아직 제 실력과 지식으로는 배열을 무한히 많이 생성해야 할 것 같습니다만... 뭔가 그건 아닌 것 같습니다. 재귀를 이용해서 정렬하려는 걸 어떻게 구현해야 기존의 데이터가 사라지거나 없어지지 않고 계속 정렬될 수 있을까요..? 간단한 아이디어만 남겨주셔도 감사하겠습니다 ㅠㅠ (자백하자면... Merge 문제 역시 재귀 정렬 방법을 생각하다 실패해 편법으로 풀었습니다..)
withcs2 Reply 3 years 46 weeks ago
포인터+재귀함수 문제라고 생각했었는데 많이 어렵나봅니다..ㅠㅠ MergeSort와 QuickSort는 Challenge로 바꾸도록 하겠습니다 무한히 많이 생성해도 되지만 전역변수를 활용하면 배열 몇 개만으로도 가능합니다. arr[100]// 전체 배열 저장할 전역변수 left_arr[100] middle_arr[100] right_arr[100] void quick_sort(왼쪽인덱스, 오른쪽인덱스) { // arr[왼쪽인덱스]부터 arr[오른쪽인덱스-1] 사이에 숫자가 하나 이상 있는 경우 pivot 기준으로 정렬하는 함수 (e.g. {5,7,2,4,1,3,0,8,6,5}) if (왼쪽인덱스 >= 오른쪽인덱스) return; 피벗에 arr[왼쪽인덱스] 저장하고 피벗 출력 arr[왼쪽인덱스]부터 arr[오른쪽인덱스-1]을 탐색하면서 피벗보다 작은 것은 left_arr[0]부터, 큰 것은 right_arr[0]부터 순서대로 저장 arr[왼쪽인덱스]부터 arr[왼쪽인덱스+피벗보다 작은 숫자 갯수-1]까지 left_arr로 새로 바꿔줌. arr[왼쪽인덱스+피벗보다 작은 숫자 갯수]부터 arr[오른쪽인덱스-피벗보다 큰 숫자 갯수-1]까지 피벗으로 바꿔줌. arr[오른쪽인덱스-피벗보다 큰 숫자 갯수]부터 arr[오른쪽인덱스-1]까지 right_arr로 바꿔줌. //여기까지 오면 피벗 기준으로 나눠진 상태입니다. (e.g. {2, 4, 1, 3, 0}{5, 5}{7, 8, 6}) // 이제 각각의 배열을 다시 재귀적으로 정렬하면 됩니다. quick_sort(왼쪽인덱스, 왼쪽인덱스+피벗보다 작은 숫자 갯수) // (e.g. {2, 4, 1, 3, 0} -> {0,1,2,3,4}) quick_sort(오른쪽인덱스-피벗보다 큰 숫자 갯수, 오른쪽인덱스) // (e.g. {7,8,6} -> {6,7,8}) } // 이제 quick_sort(0,n) 사용하면 arr[0]부터 arr[n-1]까지 정렬할 수 있습니다. arr[100]// 전체 배열 저장할 전역변수 temp_arr[100] 함수실행횟수=0 void merge_sort(왼쪽인덱스, 오른쪽인덱스) { // arr[왼쪽인덱스]부터 arr[오른쪽인덱스-1] 사이에 숫자가 하나 이상 있는 경우 반으로 나눠서 정렬하고 합치는 함수 (e.g. {1,3,4,2,5,1,3,7}) 함수실행횟수++ if (왼쪽인덱스 >= 오른쪽인덱스) return; 가운데인덱스 = (왼쪽인덱스 + 오른쪽인덱스) / 2; merge_sort(왼쪽인덱스, 가운데인덱스); // (e.g. {1,3,4,2} -> {1,2,3,4}) merge_sort(가운데인덱스, 오른쪽인덱스); // (e.g. {5,1,3,7} -> {1,3,5,7}) // 여기까지 오면 반으로 나눠서 정렬된 상태입니다. (e.g. {1, 2, 3, 4}{1, 3, 5, 7}) // 이제 두 배열을 동시에 읽어나가면서 작은 숫자를 temp에 넣고, 끝난다음 arr에 바꿔넣으면 됩니다. (e.g. {1, 2, 3, 4}{1, 3, 5, 7} -> {1, 1, 2, 3, 3, 4, 5, 7}) } // 이제 merge_sort(0,n) 사용하면 arr[0]부터 arr[n-1]까지 정렬할 수 있습니다. * 인덱스: 배열[i]에서 i를 인덱스라고 부릅니다