Skip to content

Instantly share code, notes, and snippets.

@JoeUnsung
Last active April 13, 2017 08:46
Show Gist options
  • Save JoeUnsung/9dc2f4af08f8a270dd5fd13211aa5cf5 to your computer and use it in GitHub Desktop.
Save JoeUnsung/9dc2f4af08f8a270dd5fd13211aa5cf5 to your computer and use it in GitHub Desktop.
Bottom up merge sort in C language
#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