Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Визуализация сортировки (https://javascript.ru/forum/misc/69838-vizualizaciya-sortirovki.html)

Ensei 21.07.2017 14:27

Визуализация сортировки
 
Не давно начал учить js и столкнулся с такой проблемой.
Нужно визуализировать сортировку пузырьком.
Но в функции BubbleSort перерисовка массива происходит только после выполнения сортировки, а не во время её исполнения.
Подскажите в чем ошибка и как её исправить.
Набросал следующий код:
<!DOCTYPE html>
<html>
<head>
    <title>Сортировка</title>
    <script src="js/jquery.js"></script>
    <script src="js/sort.js"></script>
</head>
<body>
	<div id="wrap">
		<input type="text" id="min">
		<input type="text" id="max">
		<input type="text" id="n">
		<p class="button Generate">Сгенерировать числа</p>
		<p class="button randomGenerate">Сгенерировать числа рандомно</p>

		<ol class='content'>

		</ol>
	</div>
</body>
</html>


function delay(ms) { 
      // Задаем точки начала измерения 
      var before = after = new Date(); 
      before = before.getTime(); 
      after = after.getTime(); 
      // В цикле меняем вторую точку, сравнивая разницу с аргуметом 
      while (after < before + ms) { 
            after = new Date(); 
            after = after.getTime(); 
      } 
}

function BubbleSort(A){ // отсортировать по возрастанию.
 var n = A.length;
 for (var i = 0; i < n-1; i++){
 	for (var j = 0; j < n-1-i; j++){
 		if (A[j+1] < A[j]){
			var t = A[j+1];
 			A[j+1] = A[j];
 			A[j] = t;
 			UpdatingPoint(A,'ol.content');//Перерисовка массива
 			console.log('Меняем местами :'+A[j+1]+' и '+A[j]);
 			delay(1000);
 		}
 	}
 } 
 return A; // На выходе сортированный по возрастанию массив A.
}

function Rand( min, max,n) {
	var A=[];
	for (var i = 0; i < n; i++) {
		if( max ) {
        	A.push(Math.floor(Math.random() * (max - min + 1)) + min);
    	} else {
    	    A.push(Math.floor(Math.random() * (min + 1)));
    	}
	}
	return A;
}

function GetImp(idImp){
	return Number(document.getElementById(idImp).value);
}

$(function(){
	x1=0;x2=0;
	$('.Generate').click(function(){
		min=GetImp('min');
		max=GetImp('max');
		n=GetImp('n');
		a=Rand(min, max,n);
		UpdatingPoint(a,'ol.content')
	});
	
	$('.randomGenerate').click(function(){
		a=Rand(-100, 100,10);
		UpdatingPoint(a,'ol.content')
	});
});

function SetPoints(A,place){//Отрисовка массива
	for (var i = 0; i < A.length; i++) {
		$(place).append("<li id='p"+i+"'>"+A[i]+"</li>");
	}
}

function DelPoints(place){//Удаление массива
		$(place).empty();
}

function UpdatingPoint(A){
	DelPoints('ol.content');
 	SetPoints(A,'ol.content');
}

рони 21.07.2017 14:44

Цитата:

Сообщение от Ensei
function delay

выкинуть и забыть, нет sleep php в js!!! а по теме ищите решение по форуму, есть несколько примеров.

Alexandroppolus 21.07.2017 14:56

Если делать одновременно сортировку и анимацию, то придется вложенный цикл переколбасить через setTimeout (ну как обычно цикл для асинхронности переделывается).

Функция сортировки будет такая, что хрен разберешь.

Потому есть смысл сначала сохранить копию массива, потом сделать сортировку, в которой записать все "ходы" (каждый ход - пара индексов), а потом уже показать анимацию - там надо будет разворачивать один for, по массиву ходов.

Ensei 21.07.2017 17:09

Цитата:

Сообщение от Alexandroppolus (Сообщение 459191)
сначала сохранить копию массива, потом сделать сортировку, в которой записать все "ходы" (каждый ход - пара индексов), а потом уже показать анимацию - там надо будет разворачивать один for, по массиву ходов.

переписал функцию BubbleSort, но на выходе получаю n одинаковых массивов.
function BubbleSort(A)       // A - массив, который нужно
{                            // отсортировать по возрастанию.
    var n = A.length;
    Steps=[];
    for (var i = 0; i < n-1; i++)
     { for (var j = 0; j < n-1-i; j++)
        { if (A[j+1] < A[j])
           {var t = A[j+1]; A[j+1] = A[j]; A[j] = t; 
           Steps.push(A);
           console.log('Меняем местами :'+A[j+1]+' и '+A[j]);}
        }
     }                     
    return Steps;    // На выходе сортированный по возрастанию массив A.
}


И добавил функцию для их поочерёдной отрисовки, но проблема осталась
function AnimalPaint(Steps){
	N=Steps.length-1;
	for (var i = 0; i < N; i++) {
		setInterval(UpdatingPoint(Steps[i]),1000);
		console.log('Step №'+i);
	}
}

рони 21.07.2017 17:37

Ensei,
Steps.push([j,i]);

рони 21.07.2017 21:34

Ensei,
function AnimalPaint(Steps){
  UpdatingPoint(Steps.shift());
 if(Steps.length) window.setTimeout(function() {
    AnimalPaint(Steps)
},1000)
}

Ensei 21.07.2017 23:26

Всем спасибо за объяснение без вас бы не разобрался)

В BubbleSort была ещё одна проблема. Строку Steps.push(A);
надо было заменить на Steps.push(A.slice());, чтобы копировалась не ссылка а сам массив.

рони 21.07.2017 23:36

Цитата:

Сообщение от Ensei
чтобы копировалась не ссылка а сам массив

а зачем вам массив, если нужна только пара?


Часовой пояс GMT +3, время: 01:54.