about summary refs log tree commit diff
path: root/usth/ICT2.1/labwork/5/Ex2.c
blob: edb5c26f0f6db899fe596a601ad98f40c8fd779d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
 * Merge sorting integers from stdin
 * Copyright (C) 2019,  Nguyễn Gia Phong
 * This software is licenced under a CC BY-SA 4.0 license
 */

#include <stdio.h>
#include <stdlib.h>

#include "construct.h"

construct *merge(construct *left, construct *right,
                 int (*compar)(const void *, const void *))
{
	if (left == NULL)
		return right;
	if (right == NULL)
		return left;
	if (compar(car(left), car(right)) <= 0)
		return cons(car(left), merge(cdr(left), right, compar));
	return cons(car(right), merge(left, cdr(right), compar));
}

construct *msort(construct *list, int (*compar)(const void *, const void *))
{
	construct *rest, *left = NULL, *right = NULL;
	while (list != NULL) {
		left = cons(car(list), left);
		rest = cdr(list);
		if (rest == NULL)
			break;
		right = cons(car(rest), right);
		list = cdr(rest);
	}
	if (left == NULL)
		return right;
	if (right == NULL)
		return left;
	return merge(msort(left, compar), msort(right, compar), compar);
}

int cmp(const void *x, const void *y)
{
	return *(int *) x - *(int *) y;
}

construct *iread(size_t n)
{
	if (!n)
		return NULL;
	int *tmp = malloc(sizeof(int));
	scanf("%d", tmp);
	return cons(tmp, iread(n - 1));
}

void iprint(construct *list)
{
	if (list == NULL) {
		putchar(10);
	} else {
		printf("%d ", *(int *) car(list));
		iprint(cdr(list));
	}
}

int main()
{
	size_t n;

	scanf("%zu", &n);
	iprint(msort(iread(n), cmp));

	return 0;
}