<!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>
body {
font-family: 'Arial', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
background-color: #f5f5f5;
padding: 20px;
}
h1 {
color: #333;
margin-bottom: 30px;
}
.container {
width: 80%;
max-width: 800px;
margin: 0 auto;
}
.array-container {
display: flex;
justify-content: center;
align-items: flex-end;
height: 400px;
margin-bottom: 30px;
background-color: white;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
padding: 20px;
}
.array-bar {
width: 30px;
margin: 0 2px;
background-color: #4CAF50;
transition: height 0.3s ease, background-color 0.3s ease;
border-radius: 3px 3px 0 0;
position: relative;
}
.array-bar.comparing {
background-color: #FF5722;
}
.array-bar.sorted {
background-color: #2196F3;
}
.array-bar.swapping {
background-color: #9C27B0;
}
.bar-value {
position: absolute;
top: -25px;
width: 100%;
text-align: center;
font-size: 12px;
color: #333;
}
.controls {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
}
button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
button:hover {
background-color: #45a049;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.speed-control {
display: flex;
align-items: center;
gap: 10px;
}
.speed-control label {
font-weight: bold;
}
.speed-control input {
width: 150px;
}
.info {
margin-top: 20px;
padding: 15px;
background-color: #e9f7ef;
border-radius: 4px;
color: #333;
text-align: center;
}
.sponsor {
margin-top: 30px;
font-size: 14px;
color: #666;
text-align: center;
}
.sponsor a {
color: #4CAF50;
text-decoration: none;
}
.sponsor a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>排序算法可视化</h1>
<div class="controls">
<button id="generate-btn">生成新数组</button>
<button id="bubble-sort-btn">冒泡排序</button>
<button id="reset-btn">重置</button>
</div>
<div class="speed-control">
<label for="speed">排序速度:</label>
<input type="range" id="speed" min="1" max="10" value="5">
</div>
<div class="array-container" id="array-container"></div>
<div class="info" id="info">
点击"生成新数组"创建随机数组,然后选择排序算法开始可视化。
</div>
<div class="sponsor">
</div>
</div>
<script>
// 全局变量
let array = [];
let animationSpeed = 200;
let isSorting = false;
let animationQueue = [];
// DOM元素
const arrayContainer = document.getElementById('array-container');
const generateBtn = document.getElementById('generate-btn');
const bubbleSortBtn = document.getElementById('bubble-sort-btn');
const resetBtn = document.getElementById('reset-btn');
const speedControl = document.getElementById('speed');
const infoDiv = document.getElementById('info');
// 初始化
generateNewArray();
// 事件监听
generateBtn.addEventListener('click', generateNewArray);
bubbleSortBtn.addEventListener('click', startBubbleSort);
resetBtn.addEventListener('click', resetArray);
speedControl.addEventListener('input', updateSpeed);
// 生成新数组
function generateNewArray() {
if (isSorting) return;
array = [];
const arraySize = Math.floor(Math.random() * 15) + 10; // 10-24个元素
for (let i = 0; i < arraySize; i++) {
array.push(Math.floor(Math.random() * 100) + 5); // 5-104之间的随机数
}
renderArray();
infoDiv.textContent = "新数组已生成,请选择排序算法开始可视化。";
}
// 渲染数组
function renderArray() {
arrayContainer.innerHTML = '';
const maxValue = Math.max(...array);
const containerHeight = arrayContainer.clientHeight;
array.forEach((value, index) => {
const bar = document.createElement('div');
bar.className = 'array-bar';
bar.style.height = `${(value / maxValue) * (containerHeight - 30)}px`;
const valueLabel = document.createElement('div');
valueLabel.className = 'bar-value';
valueLabel.textContent = value;
bar.appendChild(valueLabel);
arrayContainer.appendChild(bar);
});
}
// 更新速度
function updateSpeed() {
animationSpeed = 220 - (speedControl.value * 20);
}
// 重置数组
function resetArray() {
if (isSorting) return;
renderArray();
infoDiv.textContent = "数组已重置为当前状态。";
}
// 开始冒泡排序
function startBubbleSort() {
if (isSorting) return;
isSorting = true;
disableButtons();
infoDiv.textContent = "冒泡排序进行中...";
// 复制数组用于排序
const sortingArray = [...array];
animationQueue = [];
// 生成动画队列
bubbleSort(sortingArray);
// 执行动画
playAnimations();
}
// 冒泡排序算法
function bubbleSort(arr) {
const n = arr.length;
for (let i = 0; i < n - 1; i++) {
for (let j = 0; j < n - i - 1; j++) {
// 添加比较动画
animationQueue.push({
type: 'compare',
indices: [j, j + 1]
});
if (arr[j] > arr[j + 1]) {
// 添加交换动画
animationQueue.push({
type: 'swap',
indices: [j, j + 1]
});
// 实际交换数组元素
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
// 添加比较结束动画
animationQueue.push({
type: 'reset',
indices: [j, j + 1]
});
}
// 标记已排序的元素
animationQueue.push({
type: 'sorted',
index: n - i - 1
});
}
// 标记最后一个元素为已排序
animationQueue.push({
type: 'sorted',
index: 0
});
}
// 播放动画
function playAnimations() {
if (animationQueue.length === 0) {
sortingComplete();
return;
}
const animation = animationQueue.shift();
const bars = document.querySelectorAll('.array-bar');
switch (animation.type) {
case 'compare':
bars[animation.indices[0]].classList.add('comparing');
bars[animation.indices[1]].classList.add('comparing');
break;
case 'swap':
const [i, j] = animation.indices;
const tempHeight = bars[i].style.height;
bars[i].style.height = bars[j].style.height;
bars[j].style.height = tempHeight;
// 交换数值显示
const tempValue = bars[i].querySelector('.bar-value').textContent;
bars[i].querySelector('.bar-value').textContent = bars[j].querySelector('.bar-value').textContent;
bars[j].querySelector('.bar-value').textContent = tempValue;
bars[i].classList.add('swapping');
bars[j].classList.add('swapping');
break;
case 'reset':
bars[animation.indices[0]].classList.remove('comparing', 'swapping');
bars[animation.indices[1]].classList.remove('comparing', 'swapping');
break;
case 'sorted':
bars[animation.index].classList.add('sorted');
break;
}
setTimeout(() => {
playAnimations();
}, animationSpeed);
}
// 排序完成
function sortingComplete() {
isSorting = false;
enableButtons();
infoDiv.textContent = "冒泡排序完成!";
}
// 禁用按钮
function disableButtons() {
generateBtn.disabled = true;
bubbleSortBtn.disabled = true;
resetBtn.disabled = true;
}
// 启用按钮
function enableButtons() {
generateBtn.disabled = false;
bubbleSortBtn.disabled = false;
resetBtn.disabled = false;
}
</script>
</body>
</html>
冒泡排序算法可视化效果实现
323

被折叠的 条评论
为什么被折叠?



