吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1174|回复: 23
收起左侧

[学习记录] 教学用冒泡排序演示动画

  [复制链接]
tt559 发表于 2026-3-15 23:23
制作了一个冒泡排序的演示动画,便于更好理解冒泡排序的原理及各轮排序过程。
请大家帮忙看看 有无需要改进的地方~


[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>冒泡排序 - 课堂教学可视化</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: "Microsoft YaHei", sans-serif;
        }

        body {
            background-color: #f5f7fa;
            padding: 20px;
            max-width: 1200px;
            margin: 0 auto;
        }

        .header {
            text-align: center;
            margin-bottom: 30px;
            color: #2d3748;
        }

        .header h1 {
            font-size: 28px;
            margin-bottom: 10px;
            color: #2b6cb0;
        }

        .header p {
            font-size: 16px;
            color: #4a5568;
        }

        .container {
            display: flex;
            flex-direction: column;
            gap: 25px;
        }

        .visual-area {
            background: white;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            min-height: 220px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
        }

        .array-container {
            display: flex;
            align-items: flex-end;
            justify-content: center;
            gap: 8px;
            height: 150px;
            margin-bottom: 20px;
        }

        .bar {
            width: 50px;
            background-color: #4299e1;
            border-radius: 4px 4px 0 0;
            display: flex;
            align-items: flex-end;
            justify-content: center;
            color: white;
            font-weight: bold;
            padding-bottom: 5px;
            transition: all 0.3s ease;
        }

        .bar-comparing {
            background-color: #f6ad55;
        }

        .bar-swapping {
            background-color: #e53e3e;
        }

        .bar-sorted {
            background-color: #38a169;
        }

        .step-info {
            font-size: 18px;
            color: #2d3748;
            text-align: center;
            min-height: 27px;
            font-weight: 500;
        }

        .control-panel {
            background: white;
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            align-items: center;
            justify-content: center;
        }

        button {
            padding: 10px 20px;
            border: none;
            border-radius: 6px;
            background-color: #2b6cb0;
            color: white;
            font-size: 16px;
            cursor: pointer;
            transition: background 0.2s;
        }

        button:hover {
            background-color: #2c5282;
        }

        button:disabled {
            background-color: #a0aec0;
            cursor: not-allowed;
        }

        .speed-control {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        input[type="range"] {
            width: 150px;
        }

        .code-area {
            background: #2d3748;
            color: #e2e8f0;
            padding: 25px;
            border-radius: 12px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        .code-area h3 {
            color: #f6ad55;
            margin-bottom: 15px;
            font-size: 20px;
        }

        pre {
            font-size: 15px;
            line-height: 1.6;
            overflow-x: auto;
        }

        .code-highlight {
            background-color: #4a5568;
            padding: 2px 4px;
            border-radius: 3px;
        }

        .teach-info {
            background: #fff3bf;
            padding: 15px;
            border-radius: 8px;
            border-left: 4px solid #d69e2e;
            color: #744210;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>冒泡排序算法可视化教学</h1>
        <p>通过动态演示理解冒泡排序核心原理:相邻元素比较、交换,大数下沉/小数上浮</p>
    </div>

    <div class="container">
        <div class="visual-area">
            <div class="array-container" id="arrayContainer"></div>
            <div class="step-info" id="stepInfo">准备就绪,点击开始演示</div>
        </div>

        <div class="control-panel">
            <button id="startBtn">开始排序</button>
            <button id="pauseBtn" disabled>暂停</button>
            <button id="resetBtn">重置数组</button>
            <button id="stepBtn">单步执行</button>
            <div class="speed-control">
                <span>演示速度:</span>
                <input type="range" id="speedSlider" min="100" max="1000" value="500" step="100">
                <span id="speedText">0.5秒</span>
            </div>
        </div>

        <div class="teach-info">
            <strong>&#128218; 课堂知识点:</strong>
            <br>1. 冒泡排序每轮循环找到当前最大元素,放到末尾
            <br>2. 相邻两个数比较,逆序则交换,顺序则不变
            <br>3. 蓝色=未处理,橙色=比较中,红色=交换中,绿色=已排序
        </div>

        <div class="code-area">
            <h3>冒泡排序核心代码(JavaScript)</h3>
            <pre id="codeDisplay">
function bubbleSort(arr) {
    <span id="code1">let len = arr.length;</span>
    <span id="code2">for(let i = 0; i < len - 1; i++) {</span>
    <span id="code3">    for(let j = 0; j < len - 1 - i; j++) {</span>
    <span id="code4">        if(arr[j] > arr[j+1]) {</span>
    <span id="code5">            // 交换元素</span>
    <span id="code6">            let temp = arr[j];</span>
    <span id="code7">            arr[j] = arr[j+1];</span>
    <span id="code8">            arr[j+1] = temp;</span>
    <span id="code9">        }</span>
    <span id="code10">   }</span>
    <span id="code11">}</span>
    <span id="code12">return arr;</span>
}
            </pre>
        </div>
    </div>

    <script>
        let originalArray = [8, 3, 5, 4, 7, 2, 6, 1];
        let currentArray = [...originalArray];
        let isRunning = false;
        let isPaused = false;
        let speed = 500;

        const arrayContainer = document.getElementById('arrayContainer');
        const stepInfo = document.getElementById('stepInfo');
        const startBtn = document.getElementById('startBtn');
        const pauseBtn = document.getElementById('pauseBtn');
        const resetBtn = document.getElementById('resetBtn');
        const stepBtn = document.getElementById('stepBtn');
        const speedSlider = document.getElementById('speedSlider');
        const speedText = document.getElementById('speedText');

        function renderArray() {
            arrayContainer.innerHTML = '';
            currentArray.forEach((num, index) => {
                const bar = document.createElement('div');
                bar.className = 'bar';
                bar.style.height = `${num * 15}px`;
                bar.textContent = num;
                arrayContainer.appendChild(bar);
            });
        }

        function clearCodeHighlight() {
            for(let i=1; i<=12; i++) {
                document.getElementById(`code${i}`).classList.remove('code-highlight');
            }
        }

        function sleep(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        async function bubbleSortVisual() {
            if(isRunning) return;
            
            isRunning = true;
            isPaused = false;
            startBtn.disabled = true;
            pauseBtn.disabled = false;
            stepBtn.disabled = true;

            let arr = [...currentArray];
            const len = arr.length;
            
            clearCodeHighlight();
            document.getElementById('code1').classList.add('code-highlight');
            stepInfo.textContent = `初始化:数组长度 = ${len}`;
            await sleep(speed);

            for(let i = 0; i < len - 1; i++) {
                clearCodeHighlight();
                document.getElementById('code2').classList.add('code-highlight');
                stepInfo.textContent = `第 ${i+1} 轮排序:寻找第 ${len-i} 大的数`;
                await sleep(speed);

                for(let j = 0; j < len - 1 - i; j++) {
                    while(isPaused) await sleep(50);
                    if(!isRunning) return;

                    clearCodeHighlight();
                    document.getElementById('code3').classList.add('code-highlight');
                    
                    const bars = document.querySelectorAll('.bar');
                    bars[j].classList.add('bar-comparing');
                    bars[j+1].classList.add('bar-comparing');
                    stepInfo.textContent = `比较:${arr[j]} 和 ${arr[j+1]}`;
                    document.getElementById('code4').classList.add('code-highlight');
                    await sleep(speed);

                    if(arr[j] > arr[j+1]) {
                        bars[j].classList.replace('bar-comparing', 'bar-swapping');
                        bars[j+1].classList.replace('bar-comparing', 'bar-swapping');
                        stepInfo.textContent = `交换:${arr[j]} > ${arr[j+1]},执行交换`;
                        
                        document.getElementById('code6').classList.add('code-highlight');
                        await sleep(speed/2);
                        document.getElementById('code7').classList.add('code-highlight');
                        await sleep(speed/2);
                        document.getElementById('code8').classList.add('code-highlight');
                        
                        let temp = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = temp;
                        currentArray = [...arr];
                        renderArray();
                        await sleep(speed);
                    }

                    bars[j].classList.remove('bar-comparing', 'bar-swapping');
                    bars[j+1].classList.remove('bar-comparing', 'bar-swapping');
                }

                const bars = document.querySelectorAll('.bar');
                bars[len - 1 - i].classList.add('bar-sorted');
                stepInfo.textContent = `第 ${i+1} 轮完成:${arr[len-1-i]} 已到达正确位置`;
                await sleep(speed);
            }

            clearCodeHighlight();
            document.getElementById('code12').classList.add('code-highlight');
            const allBars = document.querySelectorAll('.bar');
            allBars.forEach(bar => bar.classList.add('bar-sorted'));
            stepInfo.textContent = '&#9989; 排序完成!冒泡排序时间复杂度:O(n&#178;)';
            
            isRunning = false;
            startBtn.disabled = false;
            pauseBtn.disabled = true;
            stepBtn.disabled = false;
        }

        startBtn.addEventListener('click', bubbleSortVisual);

        pauseBtn.addEventListener('click', () => {
            if(isRunning){
                isPaused = !isPaused;
                pauseBtn.textContent = isPaused ? '继续' : '暂停';
            }
        });

        resetBtn.addEventListener('click', () => {
            isRunning = false;
            isPaused = false;
            currentArray = [...originalArray];
            renderArray();
            clearCodeHighlight();
            stepInfo.textContent = '已重置数组,准备就绪';
            startBtn.disabled = false;
            pauseBtn.disabled = true;
            stepBtn.disabled = false;
            pauseBtn.textContent = '暂停';
        });

        stepBtn.addEventListener('click', async () => {
            if(!isRunning){
                await bubbleSortVisual();
            }
        });

        speedSlider.addEventListener('input', () => {
            speed = parseInt(speedSlider.value);
            speedText.textContent = (speed/1000).toFixed(1) + '秒';
        });

        window.onload = renderArray;
    </script>
</body>
</html>

冒泡排序.png

免费评分

参与人数 3热心值 +3 收起 理由
outdoorreadbook + 1 热心回复!
Turmo + 1 谢谢@Thanks!
bzdqsmmz + 1 直观教学,一看就懂,支持楼主

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

DCWELLS 发表于 2026-3-16 00:02
挺直观的演示,攒攒大大
bigmojin 发表于 2026-3-16 07:12
yobues 发表于 2026-3-16 08:27
lbdcyy 发表于 2026-3-16 08:39
感觉还行,只是不会玩,效果截图的话多好
zlqhysy 发表于 2026-3-16 08:47
动画演示过程很明朗的
hainanyu 发表于 2026-3-16 08:47
这个可以用在PPT吗,还是WPS?
threeidiots 发表于 2026-3-16 09:07
确实直观,还有其他排序算法吗
yearnxiao 发表于 2026-3-16 09:12
什么场景需要这个?
lovezj9012 发表于 2026-3-16 09:15
动画演示很直观,容易理解。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-6-18 16:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表