Skip to content

Commit 2f2c670

Browse files
committed
Implement q_sort function
The q_sort function uses a top-down merge sort algorithm to recursively divide the queue into two halves at the middle node, identified by front-end pointer traversal. It sorts each half and merges them with q_merge_two helper function. The q_merge_two compares adjacent elements from both halves using strcmp and builds the sorted list in head based on the descend parameter. Change-Id: Ibda66d6609df46efe52b9abb1eef5d9dda1e24f9
1 parent 3d4c601 commit 2f2c670

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

queue.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,57 @@ void q_reverseK(struct list_head *head, int k)
223223
list_splice_init(&sub_list, cur_head);
224224
}
225225

226+
static void q_merge_two(struct list_head *head,
227+
struct list_head *left,
228+
struct list_head *right,
229+
bool descend)
230+
{
231+
struct list_head *l = left->next;
232+
struct list_head *r = right->next;
233+
234+
while (l != left && r != right) {
235+
const element_t *l_elem = list_entry(l, element_t, list);
236+
const element_t *r_elem = list_entry(r, element_t, list);
237+
238+
int cmp = strcmp(l_elem->value, r_elem->value);
239+
if (descend ? (cmp >= 0) : (cmp <= 0)) {
240+
l = l->next;
241+
list_move_tail(l->prev, head);
242+
} else {
243+
r = r->next;
244+
list_move_tail(r->prev, head);
245+
}
246+
}
247+
/* Append remaining nodes */
248+
if (l != left)
249+
list_splice_tail(left, head);
250+
if (r != right)
251+
list_splice_tail(right, head);
252+
}
253+
226254
/* Sort elements of queue in ascending/descending order */
227-
void q_sort(struct list_head *head, bool descend) {}
255+
void q_sort(struct list_head *head, bool descend)
256+
{
257+
if (!head || list_empty(head) || list_is_singular(head))
258+
return;
259+
260+
struct list_head *front = head->next;
261+
struct list_head *end = head->prev;
262+
/* Find the middle node of the linked list */
263+
while (front != end && front->next != end) {
264+
front = front->next;
265+
end = end->prev;
266+
}
267+
struct list_head *mid = end;
268+
269+
LIST_HEAD(left);
270+
LIST_HEAD(right);
271+
list_splice_tail_init(head, &right);
272+
list_cut_position(&left, &right, mid->prev);
273+
q_sort(&left, descend);
274+
q_sort(&right, descend);
275+
q_merge_two(head, &left, &right, descend);
276+
}
228277

229278
/* Remove every node which has a node with a strictly less/greater value
230279
* anywhere to the right side of it according to descend flag */

0 commit comments

Comments
 (0)