void merge_sort_list(ListNode *&head) { ListNode *sp = head, *fp = head->next; if (fp == NULL) return ; while(sp->next != NULL && fp->next != NULL && fp->next->next != NULL) { sp = sp->next; fp = fp->next->next; } fp = sp->next; sp->next = NULL; merge_sort_list(head); merge_sort_list(fp); ListNode newhead(0); sp = &newhead; while(head != NULL && fp != NULL) { if (head != NULL && fp != NULL) { if (head->val < fp->val) { sp->next = head; head = head->next; } else { sp->next = fp; fp = fp->next; } sp = sp->next; continue; } } if (head == NULL) { sp->next = fp; } else { sp->next = head; } head = newhead.next; }
/* Sorts the linked list, give the head, using the well known, merge sort algorithm */ void merge_sort_list(NODE **headRef) { NODE *head = *headRef; NODE *a; NODE *b; /* Base case -- length 0 or 1 */ if ((head == NULL) || (head->next == NULL)) { return; } /* Split head into 'a' and 'b' sublists */ split_in_half(head, &a, &b); /* Recursively sort the sublists */ merge_sort_list(&a); merge_sort_list(&b); /* answer = merge the two sorted lists together */ *headRef = _merge_sort_list(a, b); }
//連結リスト版マージソート struct node *merge_sort_list(struct node *x) { struct node *a, *b, *p; //連結リストに要素が無いか、1つしか無いときはそのまま返す if (x == NULL || x->next == NULL) { return x; } //連結リストをスキャンするポインタ初期化 //aは1番目の要素を示す a = x; //bは3番目の要素(もし連結リストの長さが2なら2)を指す b = x->next; if (b != NULL) { b = b->next; } //ポインタbが連結リストの末尾に到達するまでポインタaを1つ進め、ポインタbを2つ進める //ポインタbが末尾に到達した時、ポインタaは連結リストのほぼ中央の要素をさしているはずである while (b != NULL) { a = a->next; b = b->next; if (b != NULL) { b = b->next; } } //連結リストをポインタaが指す要素の直後で2つに切断する p = a->next; a->next = NULL; //切断した連結リストを個別に整列して、その結果をマージする return merge_list(merge_sort_list(x), merge_sort_list(p)); }
ListNode* sortList(ListNode* head) { if (head == NULL) return head; merge_sort_list(head); return head; }