首先,我想對快速排序的步驟進行影片處理,以了解它的行為。
參考書中的快速排序演算法(當然)很好。
但我只能查看快速排序運動的開始和結束。讓我知道如何查看 d3.js 快速排序中的每一步。(我是 JS 初學者。)
我的臨時代碼如下。提前謝謝。
索引.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html"; charset="utf-8" />
<title>Sort Viz 03</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="draw_functions.js"></script>
<script src="quickSort.js"></script>
<style>
body {
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: 30px;
color: #333;
}
/* rect {
fill: orange;
} */
#counter{
width: 100px;
height:100px;
color: black;
font: 500 60px system-ui;
}
div {
font: 1000 30px system-ui;
}
</style>
</head>
<body>
<h1 id="title0">Quick Sort</h1>
<div id="counter0">0</div>
<div id="chart0"></div>
<script>
var myData = d3.range(10);
d3.shuffle(myData);
initDraw(myData, "chart", 0);
quickSort(myData, 0, myData.length, "chart", 0);
</script>
</body>
</html>
快速排序.js:
function quickSort(items, left, right, id, num) {
if (right - left <= 1) return;
var pivot_index = Math.floor((left right) / 2);
var pivot = items[pivot_index];
swap(items, pivot_index, right - 1);
redraw(items, id, num);
var i = left;
for (j = left; j < right - 1; j) {
if (items[j] < pivot) {
swap(items, i , j);
redraw(items, id, num);
}
}
swap(items, i, right - 1);
redraw(items, id, num);
quickSort(items, left, i, id, num);
quickSort(items, i 1, right, id, num);
redraw(items, id, num);
// console.log("#####", items ,"#####", left, right, num);
}
function swap(items, i, j) {
// console.log("@@@@@", items, i, j, (i == j), "@@@@@")
var tmp = items[i];
items[i] = items[j];
items[j] = tmp;
console.log("@@@@@", items, i, j, (i == j), "@@@@@")
}
draw_functions.js:
const graphImageSizeX = 300;
const graphImageSizeY = 200;
const margin = {top: 20, right: 20, bottom: 20, left: 20};
const width = graphImageSizeX - margin.left - margin.right;
const height = graphImageSizeY - margin.top - margin.bottom;
var durationTime = 1000;
function initDraw(data, id, num) {
console.log("#####", data ,"#####", id, num);
var bandScale = d3.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width - margin.right])
.paddingInner(0.05);
d3.select("#" id num).append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" 0 "," 0 ")");
d3.select("#" id num).select("svg").select("g")
.selectAll('rect')
.data(d3.range(data.length))
.join('rect')
.attr("id", function(d, i) { return( "rect" num "_" i ); })
.attr('fill', "orange")
.attr('width', bandScale.bandwidth())
.attr('height', function(d, i) { return Math.floor(data[i] / data.length * height); })
.attr('x', function(d) { return bandScale(d); })
.attr("y", function(d, i) { return height - Math.floor(data[i] / data.length * height); })
}
async function redraw(data, id, num) {
console.log("#####", data ,"#####", id, num);
var bandScale = d3.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width - margin.right])
.paddingInner(0.05);
d3.select("#" id num).select("svg").select("g")
.selectAll('rect')
// .data(data)
// .enter()
.transition()
.duration(durationTime)
.attr('fill', "brown")
.attr('width', bandScale.bandwidth())
.attr('height', function(d, i) { return Math.floor(data[i] / data.length * height); })
.attr('x', function(d) { return bandScale(d); })
.attr("y", function(d, i) { return height - Math.floor(data[i] / data.length * height); })
}
除了:
我必須誠實地告訴你真相。這是我已經做過的。
比較
此示例在排序中逐步使用“記錄”。但是,正如你所看到的,我對合并排序失敗了。
所以,我想尋找另一種方法,不使用“錄制和回放”,而只是“掛鉤”排序程序——如果可能的話——。
否則,某些排序方法將更難(重新)播放其影片,這不是“交換”類比所描述的。(記錄的資料會很復雜。)
對不起,不夠誠實。但是在這種情況下我該怎么辦?
提前致謝。
uj5u.com熱心網友回復:
問題是你在redraw()沒有等待轉換完成的情況下呼叫(它需要 1s ie durationTime,而后續redraw呼叫必須花費幾毫秒)。
解決方案是將所有步驟保存在一個陣列中。然后稍后重新使用它來重繪每次redraw()呼叫之間的時間間隔。為此使用setInterval。
我已經創建了一個具有上述更改的作業代碼筆。
redraw()用steps.push(參考:陣列推送方法)替換所有呼叫- 排序完成后。
steps.length以大于durationTime(參考:setInterval)的時間間隔呼叫重繪時間 - 完成重繪后,
clearInterval清理setInterval(參考:clearInterval)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/414570.html
標籤:
上一篇:如何僅將最終計數列印到控制臺上?
