Last active
April 13, 2017 08:46
-
-
Save JoeUnsung/9dc2f4af08f8a270dd5fd13211aa5cf5 to your computer and use it in GitHub Desktop.
Bottom up merge sort in C language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
int *A; // 받아온 숫자를 저장하기 위한 배열을 전역변수로 선언합니다. | |
int *B; // 임시저장을 위한 배열을 전역변수로 선언합니다. 추후 동적할당을 통해 활용. | |
void Merge(int low, int mid, int high); // bottom up merge를 위한 소트 | |
int main(void) { | |
int n = 0; // 수의 갯수 | |
int cnt = 0; // 배열 세트를 카운트 하기위한 카운트 변수 선언 | |
int low = 0, mid = 1, high = 2, width = 2; // low, mid, high 변수 선언 | |
A = (int *)malloc(sizeof(int) * 999); // 배열의 동적할당 | |
// 숫자를 받아오기 위한 파일 스트림 fp 생성 | |
FILE *fp = fopen("Input.txt", "r"); | |
if (fp == NULL) { | |
puts("파일오픈 실패 \n"); | |
return -1; | |
} | |
// 숫자를 출력하기 위한 파일 스트림 fp2 생성 | |
FILE *fp2 = fopen("Output.txt", "w"); | |
if (!fp2) { | |
printf("파일 오픈 실패!\n"); | |
return -1; | |
} | |
//배열 세트를 읽어들이며 Output에 출력하기 위한 루프 생성 | |
while (1) { | |
low = 0, mid = 1, high = 2, width = 2; | |
// 배열의 길이 가져오기 | |
fscanf(fp, "%d", &n); | |
printf("%d 배열 내의 숫자 갯수 \n", n); | |
//다음 배열이 없을 경우 (0인경우) 루프 종료 | |
if (n == 0) break; | |
// 배열의 숫자 읽어오기 | |
cnt = 0; | |
for (int i = 0; i < n; i++) { | |
fscanf(fp, "%d", &A[cnt]); | |
cnt++; | |
} | |
//bottom up merge를 위해 low, mid, high를 증가시키며 정렬을 시행 | |
while (width < n) { | |
low = 0; mid = width / 2; high = width; | |
for (int i = 1; high < n; i++) { | |
low = (width*i) - width; | |
mid = width *i - (width / 2); | |
high = width * i; | |
Merge(low, mid, high); | |
} | |
width *= 2; | |
} | |
low = 0; mid = width / 2; high = width; | |
for (int i = 1; mid < n; i++) { | |
low = (width*i) - width; | |
mid = width *i - (width / 2); | |
high = width * i; | |
Merge(low, mid, high); | |
} | |
// 최종결과 출력 | |
for (int i = 0; i < n; i++) { | |
printf("%d %d \n", A[i], i); | |
} | |
//Output.txt에 정렬된 배열 저장 | |
for (int i = 0; i < n; i++) { | |
fprintf(fp2, "%d ", A[i]); | |
} | |
fprintf(fp2, "\n"); | |
} | |
fclose(fp); | |
} | |
void Merge(int low, int mid, int high) { | |
//필요한 변수 선언 | |
int length = high - low; | |
int tempCnt = 0, pre = 0, post = 0; | |
// 임시 저장을 위한 전, 후 배열 선언 | |
int tempList1[999], tempList2[999]; | |
//전반부분 배열 저장 | |
tempCnt = 0; | |
for (int i = low; i < mid; i++) { | |
tempList1[tempCnt] = A[i]; | |
tempCnt++; | |
} | |
tempList1[tempCnt++] = 999; // 배열의 끝을 999로 지정 | |
// 후반부분 배열 저장 | |
tempCnt = 0; // TempCnt 초기화 | |
for (int i = mid; i < high; i++) { | |
tempList2[tempCnt++] = A[i]; | |
} | |
tempList2[tempCnt++] = 999; | |
// tempList1, tempList2 간의 크기를 비교하며 A 배열에 저장 | |
tempCnt = low; | |
post = 0; pre = 0; | |
while (1) { | |
if (tempList2[post] <= 0) { | |
while (tempList1[pre] != 999) { | |
A[tempCnt] = tempList1[pre]; | |
tempCnt++; | |
pre++; | |
} | |
break; | |
} | |
// tempList1, tempList2에 저장된 원소들을 크기 비교하며 작은 것 우선하여 저장함 | |
if (tempList1[pre] < tempList2[post]) { | |
A[tempCnt] = tempList1[pre]; | |
pre++; | |
tempCnt++; | |
} | |
else if (tempList1[pre] > tempList2[post]) { | |
A[tempCnt] = tempList2[post]; | |
post++; | |
tempCnt++; | |
} | |
else if (tempList1[pre] == tempList2[post]) { | |
A[tempCnt] = tempList1[pre]; | |
pre++; | |
tempCnt++; | |
} | |
//배열의 끝인 999 인자를 인식했을 때, tempList2에 있는 모든 인자를 A에 저장 후 루프 종료 | |
if (tempList1[pre] == 999) { | |
while (tempList2[post] != 999) { | |
A[tempCnt] = tempList2[post]; | |
post++; | |
tempCnt++; | |
} | |
break; | |
} | |
//배열의 끝인 999 인자를 인식했을 때, tempList1에 있는 모든 인자를 A에 저장 후 루프 종료 | |
else if (tempList2[post] == 999) { | |
while (tempList1[pre] != 999) { | |
A[tempCnt] = tempList1[pre]; | |
pre++; | |
tempCnt++; | |
} | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment