diff --git a/animations/trees/level_order/index.html b/animations/trees/level_order/index.html new file mode 100644 index 0000000..44ed31f --- /dev/null +++ b/animations/trees/level_order/index.html @@ -0,0 +1,20 @@ + + + + + Binary Tree: Level Order Traversal + + + + +

Binary Tree: Level Order Traversal

+

This animation shows how to traverse a binary tree by levels. Click the "next step" button to run the animation.

+ + +
+ + +
+ + + diff --git a/animations/trees/level_order/level_order.js b/animations/trees/level_order/level_order.js new file mode 100644 index 0000000..de43949 --- /dev/null +++ b/animations/trees/level_order/level_order.js @@ -0,0 +1,405 @@ +// Author: Jidong Xiao +// first we need to create a stage +var stage = new Konva.Stage({ + container: 'container', // id of container
+ width: 2000, + height: 1000 +}); + +// Create a layer +var layer = new Konva.Layer(); +stage.add(layer); + +function makeNULL(x,y) { + let text = new Konva.Text({ + x: x, + y: y, + text: 'NULL', + id: 'nullptr', + fontSize: 18, + fontFamily: 'Calibri', + fill: '#000000', + width: 400, + padding: 20, + }); + layer.add(text); +} + +// Create a function to draw nodes +function drawNode(x, y, label) { + var circle = new Konva.Circle({ + x: x, + y: y, + id: 'node_'+label, + radius: 40, + fill: 'lightgray', + stroke: 'black', + strokeWidth: 1 + }); + layer.add(circle); + + var text = new Konva.Text({ + x: x-5, + y: y-10, + id: 'node_text_'+label, + text: label, + fontSize: 20, + fontFamily: 'Calibri', + fill: 'black' + }); + layer.add(text); +} + +// Draw lines connecting nodes +var line1 = new Konva.Line({ + points: [645, 100, 520, 180], + //points: [650, 100, 450, 200, 650, 100, 850, 200], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var line2 = new Konva.Line({ + points: [655, 100, 780, 180], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var arrow1 = new Konva.Arrow({ + points: [925, 200, 1150, 200], + pointerLength: 10, + pointerWidth: 10, + id: "arrow1", + fill: 'green', + stroke: 'green', + strokeWidth: 5, +}); + +var line3 = new Konva.Line({ + //points: [450, 200, 350, 300, 450, 200, 550, 300], + points: [495, 200, 378, 272], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var line4 = new Konva.Line({ + points: [505, 200, 572, 272], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var line5 = new Konva.Line({ + // points: [850, 200, 750, 300, 850, 200, 950, 300], + points: [795, 200, 700, 300], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var arrow2 = new Konva.Arrow({ + points: [1000, 300, 1150, 300], + pointerLength: 10, + pointerWidth: 10, + id: "arrow2", + fill: 'green', + stroke: 'green', + strokeWidth: 5, +}); + +var line6 = new Konva.Line({ + // points: [350, 300, 300, 400, 350, 300, 400, 400], + points: [345, 300, 200, 400], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var line7 = new Konva.Line({ + points: [705, 300, 800, 400], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var line8 = new Konva.Line({ + points: [805, 200, 916, 276], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var line9 = new Konva.Line({ + points: [950, 300, 900, 400, 950, 300, 1000, 400], + stroke: 'black', + strokeWidth: 1, + lineCap: 'round', + lineJoin: 'round' +}); + +var arrow3 = new Konva.Arrow({ + points: [1050, 400, 1150, 400], + pointerLength: 10, + pointerWidth: 10, + id: "arrow3", + fill: 'green', + stroke: 'green', + strokeWidth: 5, +}); + +// Create a dotted line +var dottedLine = new Konva.Line({ + points: [300, 400, 200, 600], + stroke: 'black', + strokeWidth: 2, + dash: [5, 5] +}); +var dottedLine2 = new Konva.Line({ + points: [1000, 400, 1050, 600], + stroke: 'black', + strokeWidth: 2, + dash: [5, 5] +}); + +var arrow4 = new Konva.Arrow({ + points: [1070, 600, 1150, 600], + pointerLength: 10, + pointerWidth: 10, + id: "arrow4", + fill: 'green', + stroke: 'green', + strokeWidth: 5, +}); + +var messageBox = new Konva.Rect({ + x: 150, + y: 650, + width: 800, + height: 60, + fill: 'lightblue', + stroke: 'black', + strokeWidth: 4 +}); + +var arrow = new Konva.Arrow({ + x: messageBox.x() + messageBox.width() / 2, + y: messageBox.y(), + points: [0, 0, 0, -150], + pointerLength: 20, + pointerWidth: 20, + fill: 'black', + stroke: 'black', + strokeWidth: 4 +}); + +var messageText = new Konva.Text({ + x: messageBox.x() + 10, + y: messageBox.y() + 20, + text: 'In summary, T(n) = (2^0+2^1+2^2+2^3+...+2^(n-2)) * C = O(2^(n-1)) = O((2^n)/2) = O(2^n)', + fontSize: 20, + fontFamily: 'Calibri', + fill: 'black' +}); + +drawNode(650, 100, '5'); +layer.add(line1); +layer.add(line2); +drawNode(500, 200, '3'); +drawNode(800, 200, '6'); +layer.add(line3); +layer.add(line4); +drawNode(350, 300, '2'); +drawNode(600, 300, '4'); +layer.add(line5); +drawNode(700, 300, '7'); +layer.add(line6); +layer.add(line7); +drawNode(200, 400, '1'); +drawNode(800, 400, '8'); +layer.add(line8); +line8.hide(); +layer.draw(); + +var key; +var old_key = 0; +function start() { + key = document.getElementById('textIn').value; + stage.find('#nullptr').hide(); + if(hidden_2==1){ + // show line 6 + line6.show(); + // show 2 + stage.find('#node_'+2).show(); + stage.find('#node_text_'+2).show(); + hidden_2=0; + // reset 1 + stage.find('#node_'+1).x(200); + stage.find('#node_'+1).y(400); + stage.find('#node_text_'+1).x(195); + stage.find('#node_text_'+1).y(390); + } + if(hidden_7==1){ + // show line 7 + line7.show(); + // show 7 + stage.find('#node_'+7).show(); + stage.find('#node_text_'+7).show(); + hidden_7=0; + // reset 8 + stage.find('#node_'+8).x(800); + stage.find('#node_'+8).y(400); + stage.find('#node_text_'+8).x(795); + stage.find('#node_text_'+8).y(390); + } + if(hidden_6==1){ + line5.show(); + stage.find('#node_'+6).show(); + stage.find('#node_text_'+6).show(); + // move 7 and 8 back + stage.find('#node_'+7).x(700); + stage.find('#node_'+7).y(300); + stage.find('#node_text_'+7).x(695); + stage.find('#node_text_'+7).y(290); + stage.find('#node_'+8).x(800); + stage.find('#node_'+8).y(400); + stage.find('#node_text_'+8).x(795); + stage.find('#node_text_'+8).y(390); + line7.show(); + line8.hide(); + hidden_6=0; + } + if(deleted_3==1){ + // swap 3 and 4 back + stage.find('#node_'+3).x(500); + stage.find('#node_'+3).y(200); + stage.find('#node_text_'+3).x(495); + stage.find('#node_text_'+3).y(190); + stage.find('#node_'+4).x(600); + stage.find('#node_'+4).y(300); + stage.find('#node_text_'+4).x(595); + stage.find('#node_text_'+4).y(290); + deleted_3=0; + // reset pc + pc=1; + } + if(old_key == 0){ + }else{ + // un-highlight the old node. + stage.find('#node_'+old_key).fill("lightgray"); + // show the old node + stage.find('#node_'+old_key).show(); + stage.find('#node_text_'+old_key).show(); + } + // highlight this node. + stage.find('#node_'+key).fill("red"); + layer.draw(); + old_key = key; + console.log("start"); +} + +makeNULL(130,390); +var hidden_2=0; +var hidden_6=0; +var hidden_7=0; +var deleted_3=0; +var pc=1; +function nextstep() { + if(key == 1){ + // hide this node, and show a NULL pointer. + stage.find('#node_'+key).hide(); + stage.find('#node_text_'+key).hide(); + stage.find('#nullptr').x(130); + stage.find('#nullptr').y(390); + stage.find('#nullptr').show(); + layer.draw(); + }else if(key == 2){ + line6.hide(); + stage.find('#node_'+key).hide(); + stage.find('#node_text_'+key).hide(); + stage.find('#node_'+1).x(350); + stage.find('#node_'+1).y(300); + stage.find('#node_text_'+1).x(345); + stage.find('#node_text_'+1).y(290); + hidden_2=1; + layer.draw(); + }else if(key == 3){ + if(pc==1){ + // swap 3 and 4 + stage.find('#node_'+4).x(500); + stage.find('#node_'+4).y(200); + stage.find('#node_text_'+4).x(495); + stage.find('#node_text_'+4).y(190); + stage.find('#node_'+3).x(600); + stage.find('#node_'+3).y(300); + stage.find('#node_text_'+3).x(595); + stage.find('#node_text_'+3).y(290); + deleted_3=1; + layer.draw(); + pc = pc + 1; + }else if(pc==2){ + // hide this node, and show a NULL pointer. + stage.find('#node_'+key).hide(); + stage.find('#node_text_'+key).hide(); + stage.find('#nullptr').x(535); + stage.find('#nullptr').y(260); + stage.find('#nullptr').show(); + layer.draw(); + pc = pc + 1; + } + }else if(key == 4){ + // hide this node, and show a NULL pointer. + stage.find('#node_'+key).hide(); + stage.find('#node_text_'+key).hide(); + stage.find('#nullptr').x(535); + stage.find('#nullptr').y(260); + stage.find('#nullptr').show(); + layer.draw(); + }else if(key == 5){ + }else if(key == 6){ + line5.hide(); + stage.find('#node_'+key).hide(); + stage.find('#node_text_'+key).hide(); + // move 7 and 8 + stage.find('#node_'+7).x(800); + stage.find('#node_'+7).y(200); + stage.find('#node_text_'+7).x(795); + stage.find('#node_text_'+7).y(190); + stage.find('#node_'+8).x(950); + stage.find('#node_'+8).y(300); + stage.find('#node_text_'+8).x(945); + stage.find('#node_text_'+8).y(290); + line7.hide(); + line8.show(); + hidden_6=1; + layer.draw(); + }else if(key == 7){ + line7.hide(); + stage.find('#node_'+key).hide(); + stage.find('#node_text_'+key).hide(); + stage.find('#node_'+8).x(700); + stage.find('#node_'+8).y(300); + stage.find('#node_text_'+8).x(695); + stage.find('#node_text_'+8).y(290); + hidden_7=1; + layer.draw(); + }else if(key == 8){ + // hide this node, and show a NULL pointer. + stage.find('#node_'+key).hide(); + stage.find('#node_text_'+key).hide(); + stage.find('#nullptr').x(770); + stage.find('#nullptr').y(390); + stage.find('#nullptr').show(); + layer.draw(); + //alert("End of animation! Refresh the page if you want to re-run the animation."); + } +}