Vienna

4일차 (4) 본문

Q6. 다음의 배열을 정렬한다고 가정하겠습니다.

{9,1,3,4,5,6,7,8}

이 배열은 두 번째 요소부터는 정렬은 되어 있지만 버전 3의 버블 정렬 알고리즘을 사용해도 빠른 시간 안에 정렬 작업을 마칠 수는 없습니다. 왜냐하면 맨 앞에 있는 요의 값(9)은 1회의 패스를 거쳐도 한 칸만 뒤로 옮겨지기 때문입니다. 그래서 홀수 번째의 패스는 가장 작은 요소를 맨 앞으로 옮기고 짝수 번째 패스는 가장 큰 요소를 맨 뒤로 옮기는 방식을 사용하면 (패스의 스캔 방향을 교대로 바꾸면) 이런 정렬을 더 적은 횟수로 비교를 수행할 수 있습니다. 버전 3의 프로그램을 개선하여 양방향 버블 정렬을 수행하는 프로글매을 작성하세요.

내 답변:

우선 while문에서 for 문으로 변경했다. 진행되고 있는 패스의 숫자를 하나씩 증가하게 하고, 이를 2로 나누었을 때 몫을 확인하여 홀짝여부를 확인한다.

그리고 홀수의 경우에는 끝에서부터 검사를 진행한다. 만약 작은 숫자가 뒤에 있으면 앞으로 보낸다.

짝수의 경우에는 0부터 검사를 진행한다. 만약 큰 숫자가 앞에 있으면 뒤로 보낸다.

실습 6_3의 경우 직접 count 변수를 추가하여 확인했을 때 총 35회의 교환 및 비교를 진행하고, 다음의 코드로 진행했을 때에는 (i%2==1 비교를 제외하고) 20회의 교환과 비교를 진행하는 것을 확인할 수 있었다.

void bubble(int a[], int n) {
	int start = 0, end = n - 1, last=0;
	for(int i=0; start < end;i++){
		if (i % 2 == 1) {
			for (int j = end; j > start; j--) {
				if (a[j - 1] > a[j]) {
					swap(int, a[j - 1], a[j]);
					last = j;
				}
			}
			start = last;
		}
		else {
			for (int j = start; j < end; j++) {
				if (a[j] > a[j+1]) {
					swap(int, a[j] , a[j + 1]);
					last = j;
				}
			}
			end = last;
		}
	}
}

 


정답:

일단 보기에 더 깔끔하게 작성되었다. 그런데 초반 비교문(while(left < right))을 제외하더라도 25회의 비교가 일어난다. 그래서 내가 쓴 답변과 비교해보았지만 원인을 알 수가 없다... 나중에 다시 한 번 더 봐야할 것 같다.

///*--- 양방향 버블 정렬(셰이커 정렬) ---*/
//void shaker(int a[], int n)
//{
//	int left = 0;
//	int right = n - 1;
//	int last = right;
//
//	while (left < right) {
//		int j;
//		for (j = right; j > left; j--) {
//			if (a[j - 1] > a[j]) {
//				swap(int, a[j - 1], a[j]);
//				last = j;
//			}
//		}
//		left = last;
//
//		for (j = left; j < right; j++) {
//			if (a[j] > a[j + 1]) {
//				swap(int, a[j], a[j + 1]);
//				last = j;
//			}
//		}
//		right = last;
//	}
//}

'알고리즘 문제 풀이 > Do It! 자료구조와 함께 배우는 알고리즘 입문 C언어 편' 카테고리의 다른 글

5일차 (2)  (0) 2021.11.23
5일차 (1)  (0) 2021.11.23
4일차 (3)  (0) 2021.11.22
4일차 (2)  (0) 2021.11.22
4일차 (1)  (0) 2021.11.22
Comments