我正在用React做一个Bubble Sort可视化器。
我已经做了,而且还在工作,但是我想让它是响应式的,所以我让它的条数缩小,我是用宽度和14来做的,因为一个条的宽度是8px,margin-right是6px,但是当我点击按钮的时候,除非我调整它的大小,否则它不会工作,当我调整大小的时候,它就会工作。
这是我的组件 SortingVisualization.js。
import React, { Component } from "react";
import bubbleSort from "../algorithms/bubbleSort";
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
class SortingVisualizer extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
numberOfBars: 100,
widthOfBars: 8,
width: 0,
height: 0,
};
this.bubbleSortImp = this.bubbleSortImp.bind(this);
this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
this.updateNumberOfBars = this.updateNumberOfBars.bind(this);
this.randomArray = this.randomArray.bind(this);
}
componentDidMount() {
this.updateWindowDimensions();
window.addEventListener("resize", this.updateWindowDimensions);
this.updateNumberOfBars();
window.addEventListener("resize", this.updateNumberOfBars);
this.randomArray();
window.addEventListener("resize", this.randomArray);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateWindowDimensions);
window.removeEventListener("resize", this.updateNumberOfBars);
window.removeEventListener("resize", this.randomArray);
}
updateWindowDimensions() {
this.setState({ width: window.innerWidth, height: window.innerHeight });
}
updateNumberOfBars() {
let num = Math.floor(this.state.width / 15);
this.setState({ numberOfBars: num });
}
randomArray() {
let arr = [];
for (let i = 0; i < this.state.numberOfBars; i++) {
arr.push(this.randomNumber());
}
this.setState({ list: [...arr] });
}
randomNumber() {
let randomIndex = Math.floor(Math.random() * 100) + 1;
return randomIndex;
}
async bubbleSortImp(e) {
e.preventDefault();
let arr = this.state.list;
let len = this.state.list.length;
for (let i = 0; i < this.state.numberOfBars; i++) {
await sleep(50);
bubbleSort(arr, 0, len - 1);
this.setState({ list: [...arr] });
}
}
render() {
console.log(this.state.numberOfBars);
console.log(this.state.width);
return (
<>
<div className="sortingVisualizer">
{this.state.list.map((number, index) => (
<div
key={index}
style={{
height: `${number}` * 5,
width: this.state.widthOfBars,
}}
className="visualize"
></div>
))}
</div>
<div className="buttons">
<button className="btn" onClick={this.bubbleSortImp}>
Bubble Sort
</button>
</div>
</>
);
}
}
export default SortingVisualizer;
这是我的bubbleSort.js。
let i = 0;
let j = 0;
const bubbleSort = (arr) => {
if (i < arr.length) {
for (let j = 0; j < arr.length - i - 1; j++) {
let a = arr[j];
let b = arr[j + 1];
if (a > b) {
swap(arr, j, j + 1);
}
}
}
i++;
};
const swap = (arr, a, b) => {
let temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
};
export default bubbleSort;
下面是发生的视频
这里是GitHub Repohttps:/github.comsk0lesorting-visualization。
我在你的实现中发现了一些问题,并对代码进行了相应的修改。请参考下面的组件代码和帮助性的bubbleSort代码。希望这能帮助解决你的问题。
最初的排序是不工作的,因为在 componentDidMount
你在设置 numberOfBars
用计算出的 width
但这时宽度并没有在状态中得到更新,因此默认值是 0
. 这是在做 numberOfBars
到 0
.
而在实用性方法中,排序是不发生的,一旦发生了 i >= array.lenth
因为该值不会被重置为 0
. 发现这些问题后,相应的更新了代码。
以下是更新后的代码 SortingVisualizer
,
//SortingVisualizer.js
import React, { Component } from "react";
import bubbleSort from "../algorithms/bubbleSort";
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
class SortingVisualizer extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
numberOfBars: 100,
widthOfBars: 8,
width: window.innerWidth,
height: window.innerHeight
};
this.bubbleSortImp = this.bubbleSortImp.bind(this);
this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
this.randomArray = this.randomArray.bind(this);
}
getDerivedStateFromProps = (nextProps, prevState) => {
if (
prevState.width !== window.innerWidth ||
prevState.height !== window.innerHeight
) {
return {
width: window.innerWidth,
height: window.innerHeight
};
}
};
componentDidMount() {
this.updateWindowDimensions();
window.addEventListener("resize", this.updateWindowDimensions);
this.randomArray();
window.addEventListener("resize", this.randomArray);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateWindowDimensions);
window.removeEventListener("resize", this.randomArray);
}
updateWindowDimensions() {
const width = window.innerWidth;
let num = Math.floor(width / 15);
this.setState(() => ({
width,
height: window.innerHeight,
numberOfBars: num
}));
}
randomArray() {
let arr = [];
for (let i = 0; i < this.state.numberOfBars; i++) {
arr.push(this.randomNumber());
}
this.setState(() => ({ list: [...arr] }));
}
randomNumber() {
let randomIndex = Math.floor(Math.random() * 100) + 1;
return randomIndex;
}
async bubbleSortImp(e) {
e.preventDefault();
let arr = this.state.list;
let len = this.state.list.length;
for (let i = 0; i < this.state.numberOfBars; i++) {
await sleep(50);
bubbleSort(arr, 0, len - 1);
this.setState(() => ({ list: [...arr] }));
}
}
render() {
console.log(this.state.numberOfBars);
console.log(this.state.width);
return (
<>
<div className="sortingVisualizer">
{this.state.list.map((number, index) => (
<div
key={index}
style={{
height: `${number}` * 5,
width: this.state.widthOfBars
}}
className="visualize"
></div>
))}
</div>
<div className="buttons">
<button className="btn" onClick={this.bubbleSortImp}>
Bubble Sort
</button>
</div>
</>
);
}
}
export default SortingVisualizer;
以下是该实用程序的更新代码 bubbleSort
let i = 0;
let j = 0;
const bubbleSort = arr => {
if (i < arr.length) {
for (let j = 0; j < arr.length - i - 1; j++) {
let a = arr[j];
let b = arr[j + 1];
if (a > b) {
swap(arr, j, j + 1);
}
}
} else {
i = 0;
return;
}
i++;
};
const swap = (arr, a, b) => {
let temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
};
export default bubbleSort;