思路
- 记规律
1: 需要几个泡泡:
const num = arr.length - 1个
2: 每个泡泡需要比较多少次
- 需要8个泡泡
- 第0个泡泡需要比较8次
- 第1个泡泡需要比较7次
- 第2个泡泡需要比较6次
- 需要5个泡泡
- 第0个泡泡需要比较5次
- 第1个泡泡需要比较4次
- 第2个泡泡需要比较3次
function bubbleSort(arr: number[]) {
const num = arr.length - 1;
for (let i = 0; i < num; i++) {
for (let j = 0; j < num - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
}
let arr = [3, 5, 1, 8, 2, 99, 11];
console.log(bubbleSort(arr));
再写一遍
function sort(arr: number[]) {
const count = arr.length - 1;
for (let i = 0; i < count; i++) {
const times = count - i;
for (let j = 0; j < times; j++) {
const a = arr[j];
const b = arr[j + 1];
if (a > b) change(j, j + 1);
}
}
return arr;
function change(i: number, j: number) {
const a = arr[i];
const b = arr[j];
arr[i] = b;
arr[j] = a;
}
}
let arr = [3, 5, 1, 8, 2, 99, 11];
console.log(sort(arr));
动画代码
import React, { useState, useEffect } from 'react@18';
import { createRoot } from 'react-dom@18/client';
let arr = [3, 5, 1, 8, 2, 99, 11];
let curJ = 0
const Test = function () {
useRnder()
const click = () => {
arr = [3, 5, 1, 8, 2, 99, 11];
bubbleSort(arr)
}
const List = arr.map((num, j) => {
const cur = curJ === j || curJ + 1 === j
return <div className={cur ? 'red box' : 'box'} key={num}>{num}</div>
})
return <div className='list'>
<button onClick={() => click()} >点击开始排序</button>
{
List.reverse()
}
</div>
}
const app = document.getElementById('app');
const root = createRoot(app!)
root.render(<Test />);
async function bubbleSort(arr: number[]) {
const num = arr.length - 1;
for (let i = 0; i < num; i++) {
for (let j = 0; j < num - i; j++) {
curJ = j // 额外代码
await sleep();// 额外代码
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
await sleep() // 额外代码
}
}
}
return arr;
}
function sleep(time = 1500) {
return new Promise((reso, rejc) => {
const timer = setTimeout(() => {
reso(true)
clearTimeout(timer)
}, time)
})
}
function useRnder() {
const [_, render] = useState({})
useEffect(() => {
let timer = setInterval(() => {
render({})
}, 10)
return () => clearTimeout(timer)
}, [])
}