The QuickSort Algorithm
A separate thread is useful for animation when the thread runs a recursive algorithm and the display must be redrawn many times during the recursion.
Try it: The Call Stack
How the call stack keeps track of function calls: each call pushes a frame with its own arguments and local variables, and each return pops it.
How it works
- Calling a function pushes a new frame on top of the stack; the caller pauses.
- The frame holds that call's parameters and local variables.
- When the function returns, its frame is popped and the return value goes back to the paused caller.
- A recursive function pushes one frame per call until the base case, then the frames unwind in reverse order.
Default run (17 steps): Program starts: main is about to call factorial(4). … The stack is empty again. Result: 24. Deepest point: 4 frames, 4 calls in total.
Loading the simulation…
Watching a Sort Happen
Imagine wanting to watch a sorting algorithm work instead of just reading its output. A list of colors arrives in a random order, and over several seconds you see the colors move into place one step at a time. Each change on screen corresponds to a real step inside the algorithm. This article is about building that kind of animation for a recursive algorithm, using the QuickSort algorithm as the example.
The source gives a concrete program, QuicksortThreadDemo.java, that does exactly this. It animates a recursive QuickSort that sorts randomized colors into a standard spectrum running from red to violet, in slow motion. The Start button becomes a Finish button while the sort runs, which lets the user abort the sort before it finishes on its own.
A Recursive Algorithm Is One Method Calling Itself
A recursive algorithm solves a problem by having a method call itself on smaller pieces of the problem. The call stack grows and shrinks as the work proceeds, and the ordering of steps is determined by those nested calls. Each call that is still in progress is waiting for the calls it started to finish before it can complete.
This shape matters for animation. The algorithm is not organized as a list of separate, equally sized steps waiting to be taken one at a time. Its natural structure is one method that keeps calling itself until the job is done. The diagram below shows a simplified picture of this nesting. Each box is a sort call, and the calls below the top one are the smaller pieces it hands off. The top call is the one that started the work, and it cannot finish until the calls it started have finished.
Read the diagram from the top down. Only the innermost call is actively doing work at this moment. The calls above it are suspended in the middle of their own work, each holding its place in the chain. The diagram is a simplified picture of this control flow and does not show every internal call of QuickSort.
Why a Timer Makes Recursion Awkward
Now suppose you want to animate this algorithm with a timer that fires at regular intervals. The natural plan is that each tick advances the algorithm by one step, and the display is updated after each advance. The source states the difficulty directly: it is difficult to break up a recursive algorithm into a series of method calls driven by a timer.
The reason is the shape of the work. A timer naturally produces a sequence of separate calls, each one doing a small piece and returning. A recursive algorithm does not divide itself neatly that way. Its steps are dictated by nested calls, so the program would have to find a way to stop in the middle of a chain of calls, hand control back to the timer, and later resume at exactly the same place. That is what makes the timer-driven approach awkward.
Giving the Recursion Its Own Thread
The source's recommended design is to run a single recursive method call inside a thread. This structure is easy to run in a thread. The thread can carry the entire recursion from start to finish while the rest of the program keeps responding. Once the user starts the sort, the thread takes over and runs the recursive QuickSort, and the rest of the program is free to handle other work, such as responding to the Finish button.
The reason to use a separate thread at all is that the display must be redrawn many times while the recursion is in progress. A thread gives the recursive work its own flow of control. Each time the algorithm reaches a point where something visible has changed, the program can update the display. Because the recursion runs in the thread, these redraws happen as part of the sorting process rather than as a separate schedule that must somehow keep up with it.
Redrawing the Display While the Sort Runs
Each change in the arrangement of colors is one visible event. The source describes the loop like this: each pass through the recursion can change the arrangement, and the display is refreshed as those changes happen. The loop from the decision back to the recursive call stands for the recursion continuing until nothing remains to sort.
Tracing one redraw cycle
A list of four colors starts in a random order. Describe what repeats each time the display is refreshed while the recursive sort runs.
- 1Start the sort
The user presses Start, and the sorting thread begins the recursive QuickSort. The display shows the colors in their random starting order.
- 2Make a change
The recursion reaches a point where the arrangement of colors changes. The thread records that something visible has changed.
- 3Refresh the display
The program redraws the colors so the screen shows the new arrangement. Because this happens inside the sorting flow, the picture matches the algorithm's current state.
- 4Continue the recursion
The recursion keeps going on the smaller pieces it has not yet finished. Another change may follow, and another redraw will happen when it does.
- 5Stop when nothing remains
The loop ends when the recursion has nothing left to sort. The final redraw shows the colors arranged from red to violet.
Each cycle repeats the same pattern: the sorting thread changes the arrangement, the change is shown on screen, and the recursion continues. The display is redrawn many times, and each redraw reflects a real step of the algorithm.
The array of colors is the state that connects the two halves of the program. The sorting thread changes that array, and the drawing code reads the array's current contents to decide what to show. Since both use the same array, the picture on screen reflects the array as the recursion leaves it at that moment.
Mistakes When Animating a Recursive Sort
Common mistake Splitting the recursion into timer ticks because it looks like a list of steps
What it looks likeTrying to advance a recursive sort by one call each time a timer fires.
Why it failsThe source states that it is difficult to break a recursive algorithm into a series of timer-driven method calls, because its natural structure is one method that keeps calling itself.
Do this insteadKeep the recursive sort as a single method call and run it in a thread that carries it from start to finish.
Common mistake Assuming the display will update itself without any redraw
What it looks likeChanging the array during the sort and expecting the screen to show the change automatically.
Why it failsThe display must be redrawn many times during the recursion. The screen does not reflect the array unless the program asks for a redraw.
Do this insteadRequest a redraw each time the algorithm reaches a point where something visible has changed.
Common mistake Thinking the thread is only there to make the program faster
What it looks likeAdding a thread expecting the sort to finish sooner.
Why it failsThe source gives the reason for the thread as the need to redraw the display many times while the recursion is in progress, not speed.
Do this insteadUse the thread to give the recursive work its own flow of control so that redraws happen as part of the sorting process.
Practice: Explaining the Design Choice
A teammate proposes animating a recursive QuickSort by putting one timer tick in front of each recursive call, so that every call waits for the next tick before it runs. Using the ideas in this article, explain why this design is awkward and describe the structure the source recommends instead.
Hints
- Think about what the source says is difficult: breaking a recursive algorithm into a series of timer-driven method calls.
- Consider where the recursion would have to pause and how it would resume from the same point.
- The recommended structure keeps the recursive method whole and runs it inside a thread.
Key Takeaways
- A recursive algorithm is naturally one method that calls itself on smaller pieces, so its structure is not a list of equal steps that a timer can easily advance.
- Splitting a recursive algorithm into a series of timer-driven method calls is difficult, so the source recommends running a single recursive method call inside a thread.
- The thread carries the whole recursion while the rest of the program keeps responding, and the display is redrawn each time something visible changes.
- The array of colors is the shared state: the sorting thread changes it and the drawing code reads it to show the current arrangement.