Нужно ответить на один вопрос - Надо понять, почему алгоритм, как он запрограммирован в quick_sort.cpp, всегда заканчивает работу. Заметно, что функция quick_sort не вызывает рекурсивно себя, только если на входе левая и правая граница совпадают: if (l==r) return;. Почему не бывает так, что для некоторого N мы достигнем ситуации, когда расстояние между l и r равно 1, после чего снова вызовется quick_sort с расстоянием между l и r равным 1, и так далее до бесконечности.