我设法在p5.js中完成了一个合并排序,以对不同的长度行进行排序,但无法弄清楚如何真正显示它们正在排序。即显示它们未排序,然后在排序时更新其位置。我不确定是否可以通过一种简便的方式来实现当前代码的编写方式,或者是否需要在每个阶段之后拆分排序功能并重新绘制?
LRESULT CALLBACK MainWindow::MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_NCCREATE:
{
CREATESTRUCT *pcs = (CREATESTRUCT*)lParam;
//MainWindow* mainWindow = (MainWindow*)pcs->lpCreateParams;
//mainWindow->hwnd = hWnd;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)pcs->lpCreateParams);
/*Taskbar *taskbar = new Taskbar();
taskbar->RegisterTaskbarWindow();
taskbar->CreateTaskbarWindow(hWnd);*/
/*WorkSpace *workspace = new WorkSpace();
workspace->RegisterWorkSpaceWindow();
workspace->CreateWorkSpaceWindow(hWnd);*/
return TRUE;
}
break;
case WM_CREATE:
{
ShowWindow(hWnd, SW_SHOW);
}
break;
case WM_CLOSE:
{
PostQuitMessage(0);
}
break;
case WM_DESTROY:
{
MainWindow *mainWindow = (MainWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (mainWindow) mainWindow->hwnd = 0;
return TRUE;
}
break;
case WM_LBUTTONDOWN:
{
MainWindow *mainWindow = (MainWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
POINT pointer;
pointer.x = GET_X_LPARAM(lParam);
pointer.y = GET_Y_LPARAM(lParam);
mainWindow->OnClk(&pointer);
return TRUE;
}
break;
case WM_RBUTTONDOWN:
{
MainWindow *mainWindow = (MainWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
POINT pointer;
pointer.x = GET_X_LPARAM(lParam);
pointer.y = GET_Y_LPARAM(lParam);
return TRUE;
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
var values = [];
var numLines = 500;
function setup() {
createCanvas(900, 600);
colorMode(HSB, height);
for (i = 0; i < numLines; i++) {
values[i] = (round(random(height)));
}
values = mergeSort(values);
noLoop();
}
function draw() {
background(51);
for (let i = 0; i < values.length; i++) {
let col = color(values[i], height, height);
stroke(col);
fill(col);
var location = map(i, 0, values.length, 0, width);
rect(location, height - values[i], width/numLines, height);
}
}
function mergeSort(a) {
if (a.length <= 1) {
return a;
}
var mid = Math.round((a.length / 2));
var left = a.slice(0, mid);
var right = a.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
sorted = [];
while (left && left.length > 0 && right && right.length > 0) {
if (left[0] <= right[0]) {
sorted.push(left.shift());
}
else {
sorted.push(right.shift());
}
}
return sorted.concat(left, right);
}
答案 0 :(得分:0)
为了可视化排序,我们需要在排序过程中间隔绘制。在这里,我添加了一个depth变量,以便可以控制排序的范围。每次抽奖被称为“我增加深度”,以便我们可以看到进度。
var values = [];
var numLines = 500;
function setup() {
createCanvas(900, 600);
colorMode(HSB, height);
for (i = 0; i < numLines; i++) {
values[i] = (round(random(height)));
}
frameRate(1);
}
var depth = 1;
function draw() {
background(51);
values = mergeSort(values, depth);
depth++;
for (i = 0; i < values.length; i++) {
let col = color(values[i], height, height);
stroke(col);
fill(col);
var location = map(i, 0, values.length, 0, width);
rect(location, height - values[i], width/numLines, height);
}
if (depth > 10){
noLoop();
}
}
function mergeSort(a, d) {
if (a.length <= 1) {
return a;
}
d--;
if (d < 1){
return a;
}
var mid = Math.round((a.length / 2));
var left = a.slice(0, mid);
var right = a.slice(mid);
return merge(mergeSort(left,d), mergeSort(right, d));
}
function merge(left, right) {
sorted = [];
while (left && left.length > 0 && right && right.length > 0) {
if (left[0] <= right[0]) {
sorted.push(left.shift());
}
else {
sorted.push(right.shift());
}
}
return sorted.concat(left, right);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
答案 1 :(得分:0)
此答案使用非递归合并排序,保留排序阶段的历史记录。整个排序是在绘制之前执行的,然后绘制所有阶段的步骤,以便我们可以看到算法如何移动线条来实现排序。该代码改编自Mike Bostock的可视化算法。
https://bost.ocks.org/mike/algorithms/ https://bl.ocks.org/mbostock/1b5450d525babd28425f
var values = [];
var numLines = 500;
var sortHist = [];
function setup() {
createCanvas(900, 600);
colorMode(HSB, height);
for (i = 0; i < numLines; i++) {
values[i] =random(height);
}
sortHist = mergeSort(values);
frameRate(1);
}
var historyIndex = 0;
function draw() {
background(51);
for (i = 0; i < sortHist[historyIndex].length; i++) {
let col = color(sortHist[historyIndex][i], height, height);
stroke(col);
fill(col);
var location = map(i, 0, sortHist[historyIndex].length, 0, width);
rect(location, height - sortHist[historyIndex][i], width/numLines, height);
}
historyIndex++;
if (historyIndex > sortHist.length -1){
noLoop();
}
}
function mergeSort(array) {
var arrays = [array.slice()],
n = array.length,
array0 = array,
array1 = new Array(n);
for (var m = 1; m < n; m <<= 1) {
for (var i = 0; i < n; i += (m << 1)) {
merge(i, Math.min(i + m, n), Math.min(i + (m << 1), n));
}
arrays.push(array1.slice());
array = array0, array0 = array1, array1 = array;
}
function merge(left, right, end) {
for (var i0 = left, i1 = right, j = left; j < end; ++j) {
array1[j] = array0[i0 < right && (i1 >= end || array0[i0] <= array0[i1]) ? i0++ : i1++];
}
}
return arrays;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>