如何逐渐设置正在(气泡)排序的元素的样式?

时间:2019-05-15 20:30:33

标签: javascript jquery html css

我有几个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;
}

2 个答案:

答案 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;
}