TP 9 exo2: Implement a merge sort function for the linked list.
[TD_C.git] / TP_9 / exo2 / clist.c
CommitLineData
83ec54cd 1#include <stdio.h>
4a758ce5
JB
2#include <stdlib.h>
3#include <assert.h>
83ec54cd 4#include <stdbool.h>
f8051b35
JB
5
6#include "clist.h"
7
8link_t* list_new(int value) {
8f2b2843
JB
9 link_t* link_new;
10 link_new = malloc(sizeof(link_t));
11 link_new->value = value;
12 link_new->next = NULL;
13 return link_new;
f8051b35
JB
14}
15
16link_t* list_append(link_t* head, int value) {
17
18 if (head == NULL) {
19 return head = list_new(value);
20 } else {
21 link_t* head_first = head;
22 while (head->next != NULL) {
23 head = head->next;
24 }
25 head->next = list_new(value);
26 return head_first;
27 }
28}
29
30link_t* list_prepend(link_t* head, int value) {
31 link_t* first_link = list_new(value);
32
33 first_link->next = head;
34 return first_link;
35}
36
0d650b41 37link_t* list_insert(link_t* head, unsigned index, int value) {
0d650b41 38
3de00528
JB
39 if (index == 0) {
40 return list_prepend(head, value);
41 } else if (index == list_count(head)) {
42 return list_append(head, value);
43 } else {
44 link_t* link_insrt = list_new(value);
45 link_t* head_first = head;
46 link_t* head_next = NULL;
47 for (unsigned i = 0; i < index-1; i++) {
48 head = head->next;
49 }
50 head_next = head->next;
51 head->next = link_insrt;
52 head = link_insrt;
53 head->next = head_next;
54 return head_first;
0d650b41 55 }
0d650b41
JB
56}
57
58link_t* list_delete(link_t* head, unsigned index) {
0d650b41
JB
59 link_t* head_prev = NULL;
60 link_t* head_next = NULL;
74801358 61 link_t* head_ret = NULL;
0d650b41 62
abe54438
JB
63 if (head == NULL) {
64 return NULL;
65 } else if (index == 0) {
0d650b41
JB
66 head_next = head->next;
67 free(head);
68 head = head_next;
74801358 69 head_ret = head;
0d650b41 70 } else {
3de00528 71 link_t* head_first = head;
0d650b41
JB
72 for (unsigned i = 0; i < index-1; i++) {
73 head = head->next;
74 }
75 head_prev = head;
76 head = head->next;
77 head_next = head->next;
78 free(head);
79 head = head_prev;
80 head->next = head_next;
74801358
JB
81 head_ret = head_first;
82 }
83 if (head_ret != NULL) {
84 return head_ret;
85 } else {
86 return NULL;
0d650b41
JB
87 }
88}
89
970a0122
JB
90link_t* list_concat(link_t* first, link_t* second) {
91 link_t* head_first = first;
92
93 while (first->next != NULL) {
94 first = first->next;
95 }
96 first->next = second;
97 return head_first;
98}
99
83ec54cd
JB
100link_t* list_sort(link_t* head) {
101 int tmp;
102 bool isswaped;
103 link_t* head_first = head;
104
105 do {
106 isswaped = false;
107 while (head->next != NULL) {
108 if (head->value > head->next->value) {
109 tmp = head->value;
110 head->value = head->next->value;
111 head->next->value = tmp;
112 isswaped = true;
113 }
114 head = head->next;
115 }
954256b7 116 /* Reloop at the beginning of the list until there's values swaped */
83ec54cd
JB
117 head = head_first;
118 } while (isswaped);
119 return head_first;
120}
121
4a758ce5
JB
122static link_t* _list_merge_sort(link_t* head1, link_t* head2) {
123 link_t* head_result = NULL;
124
125 if (head1 == NULL) {
126 return head2;
127 }
128 if (head2 == NULL) {
129 return head1;
130 }
131 if (head1->value < head2->value) {
132 head_result = head1;
133 head_result->next = _list_merge_sort(head1->next, head2);
134 } else {
135 head_result = head2;
136 head_result->next = _list_merge_sort(head1, head2->next);
137 }
138 return head_result;
139}
140
141link_t* list_merge_sort(link_t* head) {
142 link_t* head1;
143 link_t* head2;
144
145 if (head == NULL || head->next == NULL) {
146 return head;
147 }
148
149 head1 = head;
150 head2 = head->next;
151 while (head2 != NULL && head2->next != NULL) {
152 head = head->next;
153 head2 = head->next->next;
154 }
155 head2 = head->next;
156 head->next = NULL;
157
158 head1 = list_merge_sort(head1);
159 head2 = list_merge_sort(head2);
160 return _list_merge_sort(head1, head2);
161}
162
f8051b35 163unsigned list_count(link_t* head) {
65544a82 164 unsigned count = 0;
f8051b35 165
8f2b2843 166 while (head != NULL) {
f8051b35
JB
167 ++count;
168 head = head->next;
169 }
170 return count;
171}
172
173void list_set(link_t* head, unsigned index, int value) {
8f2b2843 174 unsigned count = 0;
f8051b35 175
8f2b2843
JB
176 while (head != NULL && count < index) {
177 ++count;
f8051b35
JB
178 head = head->next;
179 }
8f2b2843 180 if (head != NULL) { head->value = value; }
f8051b35
JB
181}
182
183int list_get(link_t* head, unsigned index) {
8f2b2843
JB
184 unsigned count = 0;
185
186 while (head != NULL && count < index) {
187 ++count;
188 head = head->next;
189 }
190 if (head != NULL) {
f8051b35 191 return head->value;
8f2b2843 192 } else {
f8051b35
JB
193 return -1;
194 }
195}
196
74801358 197void list_clear(link_t* head) {
8f2b2843 198 link_t* next_link = NULL;
f8051b35 199
74801358
JB
200 while (head != NULL) {
201 next_link = head->next;
202 free(head);
203 head = next_link;
f8051b35
JB
204 }
205}
83ec54cd
JB
206
207void list_display_values(link_t* head) {
65544a82 208 unsigned i = 0;
83ec54cd
JB
209
210 printf("------Begin------\n");
211 while (head != NULL) {
212 printf("value at [%d]=%d\n", i, head->value);
213 head = head->next;
214 i++;
215 }
216 printf("------End------\n");
217}