linkedList* mergeSort(linkedList* li) { linkedList* L1 = li; linkedList* L2; if (L1->num == 1) return L1; int k = (L1->num) / 2; L2 = partition(L1, k); L1 = mergeSort(L1); L2 = mergeSort(L2); return merge(L1, L2); } linkedList * partition(linkedList* L, int k) { linkedList* re = init(); node* temp = L->Header; re->num = L->num - k; L->num = k; while (temp && k > 0) { temp = temp->next; k--; } re->Header->next = temp->next; temp->next = NULL; return re; } linkedList * merge(linkedList* L1, linkedList* L2) { node* tmp1 = L1->Header->next; node* tmp2 = L2->Header->next; linkedList * L = init(); node* tmp3; if (tmp1->key <= tmp2->key) { L->Header->next = tmp1; tmp1 = tmp1->next; } else { L->Header->next = tmp2; tmp2 = tmp2->next; } tmp3 = L->Header->next; while (tmp1 && tmp2) { if (tmp1->key <= tmp2->key) { tmp3->next = tmp1; tmp3 = tmp3->next; tmp1 = tmp1->next; } else { tmp3->next = tmp2; tmp3 = tmp3->next; tmp2 = tmp2->next; } } while (tmp1) { tmp3->next = tmp1; tmp3 = tmp3->next; tmp1 = tmp1->next; } while(tmp2) { tmp3->next = tmp2; tmp3 = tmp3->next; tmp2 = tmp2->next; } L->num = L1->num + L2->num; return L; }
#include <stdio.h> #include <stdlib.h> //더미 노드 있는 연결리스트 typedef struct node { int key; struct node * next; }node; typedef struct linkedList { struct node* Header; int num; }linkedList; linkedList * init() { linkedList* li = (linkedList*)malloc(sizeof(linkedList)); li->Header = (node*)malloc(sizeof(node)); li->Header->next = NULL; li->num = 0; return li; } node* createNode(int key) { node* new = (node*)malloc(sizeof(node)); new->key = key; new->next = NULL; return new; } void addNode(linkedList* li, int key) { node* new = createNode(key); node* temp = li->Header; while (temp->next) { temp = temp->next; } temp->next = new; li->num++; } void printList(linkedList* li) { node* tmp = li->Header->next; for (int i = 0; i < li->num; i++) { printf(" %d", tmp->key); tmp = tmp->next; } printf("\n"); } linkedList * merge(linkedList* L1, linkedList* L2) { node* tmp1 = L1->Header->next; node* tmp2 = L2->Header->next; linkedList * L = init(); node* tmp3; if (tmp1->key <= tmp2->key) { L->Header->next = tmp1; tmp1 = tmp1->next; } else { L->Header->next = tmp2; tmp2 = tmp2->next; } tmp3 = L->Header->next; while (tmp1 && tmp2) { if (tmp1->key <= tmp2->key) { tmp3->next = tmp1; tmp3 = tmp3->next; tmp1 = tmp1->next; } else { tmp3->next = tmp2; tmp3 = tmp3->next; tmp2 = tmp2->next; } } while (tmp1) { tmp3->next = tmp1; tmp3 = tmp3->next; tmp1 = tmp1->next; } while(tmp2) { tmp3->next = tmp2; tmp3 = tmp3->next; tmp2 = tmp2->next; } L->num = L1->num + L2->num; return L; } linkedList * partition(linkedList* L, int k) { linkedList* re = init(); node* temp = L->Header; re->num = L->num - k; L->num = k; while (temp && k > 0) { temp = temp->next; k--; } re->Header->next = temp->next; temp->next = NULL; return re; } linkedList* mergeSort(linkedList* li) { linkedList* L1 = li; linkedList* L2; if (L1->num == 1) return L1; int k = (L1->num) / 2; L2 = partition(L1, k); L1 = mergeSort(L1); L2 = mergeSort(L2); return merge(L1, L2); } int main() { int n; int key; linkedList* li = init(); scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &key); addNode(li, key); } li = mergeSort(li); printList(li); }
< 시간 복잡도 계산 >
분할 단계 : 비교 연산과 이동 연산이 수행 되지 않는다.
합병 단계 : 이진 트리로 도식화 할 수 있다. 트리의 높이는 log n 이고 한번의 합병 단계에서는 n번의 비교연산을 한다.
이동 횟수: 깊이 (log n) * 이동 (2n) (=n개의 요소가 임시배열에 복사 된 뒤 다시 가져오므로) = 2nlog(n)
T(n) = nlog n(비교) + 2nlog n(이동) = O(nlog n)
다음 표를 보면 (퀵정렬,힙정렬, 합병정렬) 은
다른 정렬에 비해 효율적 이다는 것을 알수있다.