Team Ai
Apppublic

shadowsnub/Quick-Sort-Visualizer

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
app.py198 linesDownload Raw Back to root
1import gradio as gr2import random3 4# -------------------------5# QuickSort with step tracking6# -------------------------7def quick_sort_with_steps(arr):8    steps = []9 10    def record_state(label, pivot_idx=None, i=None, j=None, sorted_indices=None):11        steps.append(render_bars(arr, label, pivot_idx, i, j, sorted_indices))12 13    def partition(low, high, sorted_indices):14        pivot = arr[high]15        pivot_idx = high16 17        record_state(f"Choosing pivot arr[{high}] = {pivot}", pivot_idx=pivot_idx, sorted_indices=sorted_indices)18 19        i = low - 120        for j in range(low, high):21            record_state(f"Comparing arr[{j}] < pivot", pivot_idx, i, j, sorted_indices)22 23            if arr[j] < pivot:24                i += 125                arr[i], arr[j] = arr[j], arr[i]26                record_state(f"Swapping arr[{i}] and arr[{j}]", pivot_idx, i, j, sorted_indices)27 28        arr[i+1], arr[high] = arr[high], arr[i+1]29        sorted_indices.add(i+1)30        record_state(f"Placing pivot at {i+1}", pivot_idx=i+1, sorted_indices=sorted_indices)31 32        return i + 133 34    def quicksort(low, high, sorted_indices):35        if low < high:36            record_state(f"QuickSort range [{low}, {high}]", sorted_indices=sorted_indices)37            pivot = partition(low, high, sorted_indices)38            quicksort(low, pivot - 1, sorted_indices)39            quicksort(pivot + 1, high, sorted_indices)40        else:41            if low == high:42                sorted_indices.add(low)43                record_state(f"Single element sorted at index {low}", sorted_indices=sorted_indices)44 45    sorted_indices = set()46    record_state("Starting QuickSort")47    quicksort(0, len(arr) - 1, sorted_indices)48 49    record_state("All elements sorted", sorted_indices=sorted_indices)50    return steps51 52 53# -------------------------54# Render bars as HTML55# -------------------------56def render_bars(arr, label, pivot_idx=None, i=None, j=None, sorted_indices=None):57    if sorted_indices is None:58        sorted_indices = set()59 60    max_height = max(arr) if arr else 161 62    bars_html = "<div style='display:flex;gap:4px;align-items:flex-end;height:200px;'>"63 64    for idx, val in enumerate(arr):65        height = int((val / max_height) * 180 + 20)66 67        color = "#6ca0dc"  # default blue-gray68 69        if idx in sorted_indices:70            color = "#4CAF50"         # green71        elif idx == pivot_idx:72            color = "#e74c3c"         # red73        elif idx == i or idx == j:74            color = "#f1c40f"         # yellow75 76        bars_html += f"""77        <div style="78            width: 18px;79            height:{height}px;80            background:{color};81            border-radius:4px;82            display:flex;83            align-items:center;84            justify-content:center;85            font-size:10px;86            color:white;87        " title="Index {idx}, Value {val}">88        </div>89        """90 91    bars_html += "</div>"92 93    return f"""94        <h4 style="margin-bottom:6px;">{label}</h4>95        {bars_html}96    """97 98 99# -------------------------100# UI Callbacks101# -------------------------102def generate(size):103    size = int(size)104    arr = random.sample(range(10, 99), size)105    frames = quick_sort_with_steps(arr.copy())106 107    return (108        frames,109        frames[0],110        gr.update(minimum=0, maximum=len(frames) - 1, value=0, interactive=True)111    )112 113 114def change_step(step, frames):115    step = int(step)116    return frames[step]117 118 119def prev_step(step, frames):120    return max(0, step - 1), frames[max(0, step - 1)]121 122 123def next_step(step, frames):124    return min(len(frames) - 1, step + 1), frames[min(len(frames) - 1, step + 1)]125 126 127def first_step(frames):128    return 0, frames[0]129 130 131def last_step(frames):132    idx = len(frames) - 1133    return idx, frames[idx]134 135 136# -------------------------137# Build Gradio App138# -------------------------139with gr.Blocks(title="QuickSort Visualizer") as demo:140 141    gr.Markdown("""142    # 🔄 QuickSort Visualizer  143    Step through the QuickSort algorithm with clean, colored bar animations.<br>144    **Red = Pivot | Yellow = Comparing | Blue = Normal | Green = Sorted**145    """)146 147    with gr.Row():148        size = gr.Slider(5, 40, value=15, label="Array Size")149        gen_btn = gr.Button("Generate Array", variant="primary")150 151    frames_state = gr.State([])152    current_step = gr.State(0)153 154    display = gr.HTML("<h4>Click Generate to begin.</h4>")155    step_slider = gr.Slider(0, 0, step=1, label="Step", interactive=False)156 157    with gr.Row():158        start_btn = gr.Button("⏮ Start")159        prev_btn = gr.Button("◀ Prev")160        next_btn = gr.Button("Next ▶")161        end_btn = gr.Button("End ⏭")162 163    # Generate button164    gen_btn.click(165        fn=generate,166        inputs=[size],167        outputs=[frames_state, display, step_slider]168    )169 170    # Slider control171    step_slider.change(change_step, [step_slider, frames_state], display)172 173    # Navigation buttons174    start_btn.click(175        lambda frames: first_step(frames),176        inputs=[frames_state],177        outputs=[step_slider, display]178    )179 180    end_btn.click(181        lambda frames: last_step(frames),182        inputs=[frames_state],183        outputs=[step_slider, display]184    )185 186    prev_btn.click(187        prev_step,188        inputs=[step_slider, frames_state],189        outputs=[step_slider, display]190    )191 192    next_btn.click(193        next_step,194        inputs=[step_slider, frames_state],195        outputs=[step_slider, display]196    )197 198demo.launch()