我有几个n
上带有随机数,后来我使用一些简单的气泡排序代码将它们按升序排列,我想逐步对其进行排列和添加样式,而不是立即对其进行样式化和排列
这感觉很简单,但是我无法找到divs
sleep
或正确使用for loop
函数的方法。如果突出显示了当前正在比较的两个setTimeout
。
这是到目前为止我所能做的一个例子:
divs
function bubbleSort(input) {
var swapped;
do {
swapped = false;
for (var i=0; i < input.length-1; i++) {
var div1 = $('.divRandom').eq(i);
var div2 = $('.divRandom').eq(i+1);
if (input[i] > input[i+1]) {
var temp = input[i];
input[i] = input[i+1];
input[i+1] = temp;
arrangeDivs(div1, div2);
swapped = true;
}
}
} while (swapped);
}
function arrangeDivs(div1, div2){
div1.before(div2);
div1.removeClass('divUnsorted');
div1.addClass('divSorted');
div2.removeClass('divUnsorted');
div2.addClass('divSorted');
}
$('.bubbleBtn').click(function() {
var divArray = new Array();
divArray = createArray(divArray);
//console.log(divArray);
bubbleSort(divArray);
//console.log(divArray);
});
function createArray(divArray) {
var divLength = $('.divUnsorted').length;
for (var i = 0; i < divLength; i++){
var divNumber = parseInt($('.divUnsorted').eq(i).text());
divArray.push(divNumber)
}
return divArray;
}
$('.addDivBtn').click(function(){
$('.divRandom').removeClass('divSorted');
$('.divRandom').addClass('divUnsorted');
var randomNumber = Math.floor((Math.random() * 1000) + 1);
$('<div/>', {
'class':'divRandom divUnsorted',
'text':randomNumber,
}).appendTo('.addDivRandom');
$('.divRandom').addClass('divUnsorted');
});
.divRandom {
display: inline-block;
text-align: center;
margin: 5px;
padding: 10px;
width: 100px;
font-size: 20px;
}
.addDivRandom {
text-align: center;
margin: auto;
}
.divUnsorted {
border: 2px solid green;
background-color: #9db;
}
.divSorting {
border: 2px solid darkred;
background-color: #db9;
}
.divSorted {
border: 2px solid darkblue;
background-color: #9bd;
}
答案 0 :(得分:1)
一种解决方法是更改它,以在每次交换之间增加延迟。以下逻辑重构了bubbleSort方法以使用内部IIFE。
此IIFE执行的setTimeout为0.5秒。每次执行时,它都会检查是否应该交换元素,如果需要则交换它们。如果索引不在循环末尾,它将调用IIFE来获取下一个索引,以继续进行评估。一旦到达循环末尾,如果发生了交换,它将再次调用bubbleSort以重新开始该过程。
function bubbleSort(input) {
var swapped = false;
(function swapDivs ( index ){
console.log( index );
setTimeout(function(){
if ( index < input.length - 1 ) {
var $divs = $('.divRandom'),
$div1 = $divs.eq( index ),
$div2 = $divs.eq( index + 1 );
if ( input[ index ] > input[ index + 1 ] ) {
var temp = input[ index ];
input[ index ] = input[ index + 1 ];
input[ index + 1 ] = temp;
arrangeDivs( $div1, $div2 );
swapped = true;
}
swapDivs( index + 1 );
}
else if ( swapped ) {
$('.divRandom.divSorted').toggleClass('divSorted divUnsorted');
bubbleSort( input );
}
}, 500);
})(0);
}
function arrangeDivs(div1, div2){
div1.before(div2);
div1.removeClass('divUnsorted');
div1.addClass('divSorted');
div2.removeClass('divUnsorted');
div2.addClass('divSorted');
}
$('.bubbleBtn').click(function() {
var divArray = new Array();
divArray = createArray(divArray);
//console.log(divArray);
bubbleSort(divArray);
//console.log(divArray);
});
function createArray(divArray) {
var divLength = $('.divUnsorted').length;
for (var i = 0; i < divLength; i++){
var divNumber = parseInt($('.divUnsorted').eq(i).text());
divArray.push(divNumber)
}
return divArray;
}
$('.addDivBtn').click(function(){
$('.divRandom').removeClass('divSorted');
$('.divRandom').addClass('divUnsorted');
var randomNumber = Math.floor((Math.random() * 1000) + 1);
$('<div/>', {
'class':'divRandom divUnsorted',
'text':randomNumber,
}).appendTo('.addDivRandom');
$('.divRandom').addClass('divUnsorted');
});
.divRandom {
display: inline-block;
text-align: center;
margin: 5px;
padding: 10px;
width: 100px;
font-size: 20px;
}
.addDivRandom {
text-align: center;
margin: auto;
}
.divUnsorted {
border: 2px solid green;
background-color: #9db;
}
.divSorting {
border: 2px solid darkred;
background-color: #db9;
}
.divSorted {
border: 2px solid darkblue;
background-color: #9bd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="addDivRandom">
</div>
<button class="addDivBtn" style="display: block;">Add</button>
<button class="bubbleBtn" style="display: block;">Bubble</button>
答案 1 :(得分:1)
执行循环时,整个页面将必须等到完成后才能重新获得控制权。这包括您在DOM中所做的任何更改,因此浏览器将等待整个执行过程向您显示结果。
可以避免这样的情况:如果您改为运行排序的每个步骤,安排下一步,然后将控制权交还给浏览器并重复。以这种方式,您可以在排序时更新UI。为此,您可以使用setTimeout
-您将递归调度函数,直到排序操作完成。
您的排序功能需要进行一些微小的更改-不会出现循环,从而使import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import arrayChunk from 'lodash.chunk';
import 'bootstrap/dist/css/bootstrap.min.css';
const IndexPage = () => {
const rawData = [1, 2, 3, 4, 5, 6];
const chunkedData = arrayChunk(rawData, 3)
return (
<div>
<div className="container">
{chunkedData.map((row, rowIndex) => {
return (<div key={rowIndex} className="row">{
row.map((col, colIndex) => {return (<div key={colIndex} className="col-sm">{col}</div>)})
}</div>)
}
)}
</div>
</div>
);
};
ReactDOM.render(<IndexPage />, document.getElementById('root'));
变量过时。您可以通过将当前索引传递给swapped
的每次执行来跟踪当前索引。当没有其他要排序的内容时,您可以完成排序。我已经注释掉了不需要明确更改的代码:
bubbleSort
function bubbleSort(input, i = 0) {
//nothing to sort
if (input.length == 0) {
console.log("sorting complete");
return;
}
//var swapped; -> not needed
//do { -> not needed
//swapped = false; -> not needed
//for (var i=0; i < input.length-1; i++) { -> not needed
var div1 = $('.divRandom').eq(i);
var div2 = $('.divRandom').eq(i+1);
if (input[i] > input[i+1]) {
var temp = input[i];
input[i] = input[i+1];
input[i+1] = temp;
arrangeDivs(div1, div2);
//swapped = true; -> not needed
}
//} -> not needed - closes the for-loop
var next;
if (i == input.length) {
//loop back to the start
next = 0;
//exclude the last element - it's already sorted
input = input.slice(0, -1)
} else {
//move the index
next = i + 1
}
//schedule next step - you can change the delay to control the speed of the updates
setTimeout(bubbleSort, 450, input, next)
//} while (swapped); -> not needed
}
function arrangeDivs(div1, div2){
div1.before(div2);
div1.removeClass('divUnsorted');
div1.addClass('divSorted');
div2.removeClass('divUnsorted');
div2.addClass('divSorted');
}
$('.bubbleBtn').click(function() {
var divArray = new Array();
divArray = createArray(divArray);
//console.log(divArray);
bubbleSort(divArray);
//console.log(divArray);
});
function createArray(divArray) {
var divLength = $('.divUnsorted').length;
for (var i = 0; i < divLength; i++){
var divNumber = parseInt($('.divUnsorted').eq(i).text());
divArray.push(divNumber)
}
return divArray;
}
$('.addDivBtn').click(function(){
$('.divRandom').removeClass('divSorted');
$('.divRandom').addClass('divUnsorted');
var randomNumber = Math.floor((Math.random() * 1000) + 1);
$('<div/>', {
'class':'divRandom divUnsorted',
'text':randomNumber,
}).appendTo('.addDivRandom');
$('.divRandom').addClass('divUnsorted');
});
.divRandom {
display: inline-block;
text-align: center;
margin: 5px;
padding: 10px;
width: 100px;
font-size: 20px;
}
.addDivRandom {
text-align: center;
margin: auto;
}
.divUnsorted {
border: 2px solid green;
background-color: #9db;
}
.divSorting {
border: 2px solid darkred;
background-color: #db9;
}
.divSorted {
border: 2px solid darkblue;
background-color: #9bd;
}
因此,除此之外-如果要突出显示正在排序的div,这是您可以做的-当您确定现在要检查哪个两个div时,请向其添加样式<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="addDivRandom">
</div>
<button class="addDivBtn" style="display: block;">Add</button>
<button class="bubbleBtn" style="display: block;">Bubble</button>
。下次执行该函数时,将删除所有divSorting
类并突出显示下两个类。然后,当您循环返回以重新启动计数器时,可以使最后一个元素divSorting
-它已经在其位置。
divSorted
function bubbleSort(input, i = 0) {
//nothing to sort
if (input.length == 0) {
return;
}
var div1 = $('.divRandom').eq(i);
var div2 = $('.divRandom').eq(i+1);
//reset all styles - we are soring different divs now
$("div").removeClass("divSorting");
//highlight the ones that are being examined now
div1.addClass('divSorting');
div2.addClass('divSorting');
if (input[i] > input[i+1]) {
var temp = input[i];
input[i] = input[i+1];
input[i+1] = temp;
arrangeDivs(div1, div2);
}
var next;
if (i == input.length-1) {
//loop back to the start
next = 0;
//exclude the last element - it's already sorted
input = input.slice(0, -1);
//mark the last div as sorted
$('.divRandom').eq(i).addClass("divSorted");
} else {
//move the index
next = i + 1
}
//schedule next step - you can change the delay to control the speed of the updates
setTimeout(bubbleSort, 450, input, next)
}
function arrangeDivs(div1, div2){
div1.before(div2);
}
$('.bubbleBtn').click(function() {
var divArray = new Array();
divArray = createArray(divArray);
//console.log(divArray);
bubbleSort(divArray);
//console.log(divArray);
});
function createArray(divArray) {
var divLength = $('.divUnsorted').length;
for (var i = 0; i < divLength; i++){
var divNumber = parseInt($('.divUnsorted').eq(i).text());
divArray.push(divNumber)
}
return divArray;
}
$('.addDivBtn').click(function(){
$('.divRandom').removeClass('divSorted');
$('.divRandom').addClass('divUnsorted');
var randomNumber = Math.floor((Math.random() * 1000) + 1);
$('<div/>', {
'class':'divRandom divUnsorted',
'text':randomNumber,
}).appendTo('.addDivRandom');
$('.divRandom').addClass('divUnsorted');
});
.divRandom {
display: inline-block;
text-align: center;
margin: 5px;
padding: 10px;
width: 100px;
font-size: 20px;
}
.addDivRandom {
text-align: center;
margin: auto;
}
.divUnsorted {
border: 2px solid green;
background-color: #9db;
}
.divSorting {
border: 2px solid darkred;
background-color: #db9;
}
.divSorted {
border: 2px solid darkblue;
background-color: #9bd;
}nd-color: yellow;
}