{"id":31065,"date":"2026-10-08T11:49:47","date_gmt":"2026-10-08T11:49:47","guid":{"rendered":"https:\/\/www.codemonkey.com\/?page_id=31065"},"modified":"2026-10-29T16:51:56","modified_gmt":"2026-10-29T16:51:56","slug":"data-structures","status":"publish","type":"page","link":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/","title":{"rendered":"\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Data Structure Playground<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Poppins:wght@400;500;600;700;800\" rel=\"stylesheet\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=JetBrains+Mono:wght@400;600\" rel=\"stylesheet\">\n<style>\n  :root{\n    --brown-dark:#39261F; --brown:#795535; --tan:#BF8653; --yellow:#FFC62F;\n    --lime:#9BB33F; --green:#4B571A; --gray:#54595F; --blue:#79ABCB;\n    --sky:#B0D1E5; --purple:#7A6796; --pink:#C64F61; --red:#B2372A;\n    --white:#ffffff;\n    --tint:rgba(176,209,229,.22);\n    --yellow-tint:rgba(255,198,47,.16);\n  }\n  *{box-sizing:border-box}\n  body{margin:0;font-family:'Poppins',system-ui,sans-serif;color:var(--brown-dark);background:var(--white);line-height:1.55;-webkit-font-smoothing:antialiased}\n  h1,h2,h3{font-family:'Poppins',sans-serif;margin:0}\n\n  \/* ---------- Hero ---------- *\/\n  .hero{position:relative;overflow:hidden;color:var(--white);text-align:center;padding:52px 16px 110px}\n  .eyebrow{position:relative;display:inline-block;font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;background:rgba(255,255,255,.14);padding:6px 14px;border-radius:999px;margin-bottom:14px}\n  .hero h1{position:relative;font-weight:800;text-transform:uppercase;letter-spacing:.01em;font-size:clamp(30px,5.4vw,52px);line-height:1.08;color:var(--yellow)}\n  .hero p{position:relative;max-width:640px;margin:12px auto 0;font-size:16px;opacity:.95}\n  .wave{position:absolute;left:0;right:0;bottom:-1px;width:100%;height:60px;display:block}\n  .eyebrow:focus-visible{outline:3px solid var(--purple);outline-offset:2px}\n\n  .hero{background-color:var(--green);background-image:radial-gradient(ellipse 460px 150px at 50% 50%,#4B571A 55%,rgba(75,87,26,0) 100%),url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='280' height='280' viewBox='0 0 280 280'%3E%3Cdefs%3E%3Cg id='b'%3E%3Cpath d='M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z' fill='%23E6B94A'\/%3E %3Cpath d='M268 578 C340 612 410 622 470 620 C565 616 655 562 712 505 C750 467 790 428 812 405 C790 470 730 560 640 610 C590 638 540 650 480 652 C400 652 322 622 266 592 Z' fill='%23CDA144'\/%3E %3Cpath d='M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z' fill='none' stroke='%23231F20' stroke-width='10' stroke-linejoin='round'\/%3E %3Cg fill='none' stroke='%23231F20' stroke-width='10' stroke-linecap='butt'%3E %3Cpath d='M302 618 C360 655 420 690 505 692 C620 694 730 610 812 518'\/%3E %3Cpath d='M562 648 C660 610 760 530 815 418'\/%3E %3Cpath d='M780 516 C795 485 808 452 818 420'\/%3E %3C\/g%3E %3Cpath d='M808 405 L826 340 L848 345 L843 408 C835 420 818 422 808 405 Z' fill='%23644E37' stroke='%23231F20' stroke-width='10' stroke-linejoin='round'\/%3E %3Cpath d='M249 555 C246 570 251 584 259 594 C269 588 277 580 282 572 Z' fill='%23644E37' stroke='%23231F20' stroke-width='10' stroke-linejoin='round'\/%3E%3C\/g%3E%3C\/defs%3E%3Cg opacity='.85'%3E%3Cuse href='%23b' transform='translate(55 60) rotate(-15) scale(0.11) translate(-540 -545)'\/%3E%3Cuse href='%23b' transform='translate(185 150) rotate(25) scale(0.09) translate(-540 -545)'\/%3E%3Cuse href='%23b' transform='translate(80 215) rotate(160) scale(0.1) translate(-540 -545)'\/%3E%3Cuse href='%23b' transform='translate(230 40) rotate(-50) scale(0.08) translate(-540 -545)'\/%3E%3C\/g%3E%3C\/svg%3E\");background-size:auto,280px;background-position:center,0 0;background-repeat:no-repeat,repeat}\n  .hero .bb{position:absolute;pointer-events:none}\n  .hero .bb svg{width:100%;height:auto;display:block}\n  .hero .bb.l{width:160px;left:max(16px,calc(50% - 630px));top:92px;transform:rotate(-12deg)}\n  .hero .bb.r{width:125px;right:max(16px,calc(50% - 610px));top:28px;transform:scaleX(-1) rotate(-18deg)}\n  @media (max-width:1180px){.hero .bb.l{width:96px;top:150px}.hero .bb.r{width:80px;top:14px}}\n  @media (max-width:640px){.hero .bb.l{width:58px;left:6px;top:36px}.hero .bb.r{width:50px;right:6px;top:8px}}\n  .eyebrow{text-decoration:none;color:var(--white);transition:background .15s}\n  .eyebrow:hover{background:rgba(255,255,255,.24)}\n\n\n  .lvl{flex:none}\n  .lvl .label{text-align:right}\n  .level{display:inline-flex;background:var(--tint);border-radius:999px;padding:4px;gap:4px}\n  .level button{font:700 14px 'Poppins',sans-serif;border:none;background:transparent;color:var(--gray);border-radius:999px;padding:8px 18px;cursor:pointer}\n  .level button[aria-pressed=\"true\"]{background:var(--brown-dark);color:var(--yellow)}\n  .level button:focus-visible{outline:3px solid var(--purple);outline-offset:2px}\n  .level-note{font-size:12px;color:var(--gray);margin-top:6px;text-align:right}\n  @media (max-width:640px){.lvl{order:-1;width:100%}.lvl .label,.lvl .level-note{text-align:left}}\n  body.easy .adv-only{display:none !important}\n  body.adv .easy-only{display:none !important}\n\n\n  \/* ---------- Layout ---------- *\/\n  .wrap{max-width:1160px;margin:-64px auto 48px;padding:0 16px;position:relative}\n  .card{background:var(--white);border-radius:24px;box-shadow:0 12px 34px rgba(57,38,31,.13);padding:24px}\n  .label{display:block;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--gray);margin-bottom:8px}\n  .main-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:24px;margin-top:20px}\n  @media (max-width:900px){.main-grid{grid-template-columns:1fr}}\n\n  \/* ---------- Controls ---------- *\/\n  .chips{display:flex;flex-wrap:wrap;gap:8px}\n  .chip{font:600 14px 'Poppins',sans-serif;color:var(--brown-dark);background:var(--white);border:2px solid var(--sky);border-radius:999px;padding:8px 16px;cursor:pointer;transition:background .15s,border-color .15s,transform .08s}\n  .chip:hover{border-color:var(--blue)}\n  .chip[aria-pressed=\"true\"]{background:var(--yellow);border-color:var(--yellow);box-shadow:0 3px 0 var(--tan)}\n  .chip:active{transform:translateY(2px)}\n  .chip:disabled{opacity:.5;cursor:not-allowed;transform:none}\n  .controls{display:flex;flex-wrap:wrap;gap:16px 20px;align-items:flex-end;margin-top:20px}\n  .valbox{display:flex;gap:8px;align-items:center}\n  .valbox input{width:96px;font:700 18px 'Poppins',sans-serif;color:var(--brown-dark);text-align:center;border:2px solid var(--green);border-radius:999px;padding:8px 10px;background:var(--white)}\n  .valbox input:focus{outline:3px solid var(--purple);outline-offset:2px}\n  .ops{display:flex;flex-wrap:wrap;gap:10px;flex:1}\n  .speed{min-width:150px}\n  .speed .val{font-weight:700;color:var(--brown)}\n  input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:8px;border-radius:999px;background:var(--sky);cursor:pointer}\n  input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:22px;height:22px;border-radius:50%;background:var(--yellow);border:3px solid var(--brown-dark)}\n  input[type=range]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:var(--yellow);border:3px solid var(--brown-dark)}\n\n  .btn{font:700 14px 'Poppins',sans-serif;border:none;border-radius:999px;padding:11px 20px;cursor:pointer;background:var(--yellow);color:var(--brown-dark);box-shadow:0 4px 0 var(--tan);display:inline-flex;align-items:center;justify-content:center;gap:8px;transition:transform .08s,box-shadow .08s}\n  .btn:active{transform:translateY(3px);box-shadow:0 1px 0 var(--tan)}\n  .btn.secondary{background:var(--white);border:2px solid var(--sky);box-shadow:0 4px 0 var(--sky);padding:9px 16px}\n  .btn.secondary:active{box-shadow:0 1px 0 var(--sky)}\n  .btn.icon{width:44px;height:44px;padding:0}\n  .btn.arg{background:var(--green);color:var(--white);box-shadow:0 4px 0 #2C330F}\n  .btn.arg:active{box-shadow:0 1px 0 #2C330F}\n  .btn.arg::before{content:\"x\";font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:600;background:rgba(255,255,255,.2);border-radius:6px;padding:0 6px;line-height:18px}\n  .ops-hint{font-size:12px;color:var(--gray);margin-top:8px}\n  .ops-hint b{display:inline-block;font-family:'JetBrains Mono',monospace;font-size:11px;background:var(--green);color:var(--white);border-radius:6px;padding:0 6px;line-height:18px}\n  .headrow{display:flex;flex-wrap:wrap;gap:14px 20px;align-items:flex-start;justify-content:space-between}\n  .log-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}\n  .log-head h3{margin:0}\n  .linkbtn{background:none;border:2px solid var(--sky);border-radius:999px;font:700 12px 'Poppins',sans-serif;color:var(--brown-dark);padding:3px 12px;cursor:pointer}\n  .linkbtn:hover{border-color:var(--blue)}\n  .linkbtn:disabled{opacity:.4;cursor:not-allowed}\n  .code.plain{font-family:'Poppins',sans-serif;font-size:13px}\n  .code.plain .ln{white-space:pre-wrap;padding-left:14px;text-indent:0}\n  .btn:disabled{opacity:.4;cursor:not-allowed;transform:none}\n  .btn svg{width:18px;height:18px;fill:currentColor}\n  .chip:focus-visible,.btn:focus-visible,input[type=range]:focus-visible{outline:3px solid var(--purple);outline-offset:2px}\n\n  \/* ---------- Stage ---------- *\/\n  .stage{background:var(--tint);border-radius:20px;min-height:430px;padding:28px 20px;display:flex;align-items:center;justify-content:center;flex-direction:column;position:relative;overflow:hidden}\n  .stage.shake{animation:shake .4s}\n  @keyframes shake{20%,60%{transform:translateX(-8px)}40%,80%{transform:translateX(8px)}}\n  .empty-msg{color:var(--gray);font-weight:600;font-size:15px;text-align:center;padding:20px}\n  .tag{font-size:11px;font-weight:800;letter-spacing:.1em;color:var(--brown);text-transform:uppercase;white-space:nowrap}\n\n  @keyframes drop{from{transform:translateY(-60px);opacity:0}to{transform:none;opacity:1}}\n  @keyframes flyup{to{transform:translateY(-70px);opacity:0}}\n  @keyframes slidein{from{transform:translateX(60px);opacity:0}to{transform:none;opacity:1}}\n  @keyframes slideout{to{transform:translateX(-60px);opacity:0}}\n  @keyframes popin{from{transform:scale(.2);opacity:0}to{transform:scale(1);opacity:1}}\n  @keyframes fadeout{to{transform:scale(.4);opacity:0}}\n  @keyframes pulse{50%{transform:scale(1.1)}}\n\n  \/* stack *\/\n  .stack-wrap{display:flex;flex-direction:column;align-items:center}\n  .stack-col{display:flex;flex-direction:column-reverse;gap:6px;width:190px;min-height:60px;padding:0 10px}\n  .stack-base{width:230px;height:10px;border-radius:999px;background:var(--brown-dark);margin-top:8px}\n  .stack-col .placeholder{color:var(--gray);font-weight:600;text-align:center;padding:16px 0}\n  .item{position:relative;height:42px;border-radius:12px;background:var(--sky);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:18px;box-shadow:0 3px 0 rgba(57,38,31,.15)}\n  .item.top{background:var(--yellow)}\n  .item.peek{background:var(--purple);color:var(--white);animation:pulse .5s 2}\n  .item .tag{position:absolute;left:calc(100% + 14px)}\n  .item .tag::before{content:\"\\2190  \"}\n  .ds-stack .item.enter{animation:drop .4s ease-out}\n  .ds-stack .item.leave{animation:flyup .4s ease-in forwards}\n\n  \/* queue *\/\n  .queue-wrap{display:flex;align-items:center;gap:12px;width:100%;justify-content:center}\n  .q-end{font-size:12px;font-weight:700;color:var(--gray);text-align:center;line-height:1.2}\n  .q-end b{display:block;font-size:22px;color:var(--brown)}\n  .queue-row{display:flex;gap:8px;padding:14px;border-top:4px solid var(--brown-dark);border-bottom:4px solid var(--brown-dark);min-height:96px;align-items:center;min-width:120px;flex-wrap:wrap;justify-content:center;max-width:620px}\n  .qitem{position:relative;width:52px;height:52px;border-radius:14px;background:var(--sky);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:18px;box-shadow:0 3px 0 rgba(57,38,31,.15)}\n  .qitem.front{background:var(--yellow)}\n  .qitem.peek{background:var(--purple);color:var(--white);animation:pulse .5s 2}\n  .qitem .tag{position:absolute;top:calc(100% + 20px);left:50%;transform:translateX(-50%)}\n  .qitem.enter{animation:slidein .4s ease-out}\n  .qitem.leave{animation:slideout .4s ease-in forwards}\n\n  \/* linked list *\/\n  .ll{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px 0;max-width:100%}\n  .headptr{background:var(--brown-dark);color:var(--yellow);font-size:12px;font-weight:800;letter-spacing:.1em;border-radius:999px;padding:6px 12px}\n  .node{display:flex;border:3px solid var(--brown-dark);border-radius:14px;overflow:hidden;background:var(--white);height:54px;box-shadow:0 3px 0 rgba(57,38,31,.15)}\n  .node .nv{min-width:52px;padding:0 10px;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:18px;background:var(--sky)}\n  .node .np{width:30px;border-left:3px solid var(--brown-dark);display:flex;align-items:center;justify-content:center}\n  .node .np::after{content:\"\";width:10px;height:10px;border-radius:50%;background:var(--brown-dark)}\n  .node.cur .nv{background:var(--yellow)}\n  .node.found .nv{background:var(--lime);color:var(--white)}\n  .node.new .nv{background:var(--lime);color:var(--white)}\n  .node.del .nv{background:var(--pink);color:var(--white)}\n  .node.enter{animation:popin .4s ease-out}\n  .node.leave{animation:fadeout .4s ease-in forwards}\n  .arr{display:inline-block;width:34px;height:3px;background:var(--brown-dark);position:relative;margin:0 4px 0 2px}\n  .arr::after{content:\"\";position:absolute;right:-2px;top:-6px;border-left:10px solid var(--brown-dark);border-top:7.5px solid transparent;border-bottom:7.5px solid transparent}\n  .nullbox{font-family:'JetBrains Mono',monospace;font-weight:600;font-size:14px;color:var(--gray);border:2px dashed var(--gray);border-radius:10px;padding:6px 10px}\n\n  \/* bst *\/\n  .tree{width:100%;height:auto;display:block;max-height:420px}\n  .tree text{font-family:'Poppins',sans-serif}\n  .edge{stroke:var(--brown-dark);stroke-width:3;stroke-linecap:round}\n  .edge.hot{stroke:var(--tan);stroke-width:5}\n  .bn circle{fill:var(--white);stroke:var(--brown-dark);stroke-width:3}\n  .bn text{font-size:15px;font-weight:800;text-anchor:middle;fill:var(--brown-dark)}\n  .bn.path circle{fill:var(--yellow)}\n  .bn.found circle,.bn.new circle{fill:var(--lime)}\n  .bn.found text,.bn.new text{fill:var(--white)}\n  .bn.del circle{fill:var(--pink)}\n  .bn.del text,.bn.succ text,.bn.visit text{fill:var(--white)}\n  .bn.succ circle,.bn.visit circle{fill:var(--purple)}\n  .bn.done circle{fill:var(--sky)}\n  .bn{transform-box:fill-box;transform-origin:center}\n  .bn.enter{animation:popin .45s ease-out}\n  .bn.leave{animation:fadeout .4s ease-in forwards}\n  .trav{display:flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:center;margin-top:8px}\n  .trav span{min-width:34px;padding:4px 8px;border-radius:999px;background:var(--purple);color:var(--white);font-weight:700;font-size:14px;text-align:center;animation:popin .3s ease-out}\n  .trav .tag{background:none;color:var(--brown);min-width:0;animation:none}\n\n  .status{margin-top:14px;border:2px dashed var(--sky);border-radius:16px;padding:12px 16px;font-weight:500;font-size:15px;display:flex;gap:12px;align-items:flex-start;min-height:52px}\n  .status .dot{flex:none;width:12px;height:12px;border-radius:50%;background:var(--yellow);margin-top:6px;box-shadow:0 0 0 4px var(--yellow-tint)}\n  .legend{display:flex;flex-wrap:wrap;gap:6px 16px;margin:12px 2px 0;font-size:13px;color:var(--gray)}\n  .legend i{display:inline-block;width:14px;height:14px;border-radius:4px;vertical-align:-2px;margin-right:6px}\n\n  \/* ---------- Panel ---------- *\/\n  .side h3{font-weight:700;font-size:15px;text-transform:uppercase;letter-spacing:.06em;margin-bottom:10px}\n  .code{background:var(--brown-dark);color:rgba(255,255,255,.82);border-radius:18px;padding:14px 0;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12.5px;overflow-x:auto}\n  .code .ttl{padding:0 16px 8px;color:var(--sky);font-size:11px;text-transform:uppercase;letter-spacing:.08em}\n  .code .ln{padding:3px 16px 3px 12px;white-space:pre;border-left:4px solid transparent}\n  .code .ln.active{background:rgba(255,198,47,.16);border-left-color:var(--yellow);color:var(--yellow);font-weight:600}\n  .stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:18px}\n  .stat{background:var(--tint);border-radius:16px;padding:12px 8px;text-align:center}\n  .stat b{display:block;font-weight:800;font-size:24px;line-height:1.1;color:var(--brown)}\n  .stat small{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--gray)}\n  .log{margin-top:18px}\n  .log ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;max-height:190px;overflow:auto}\n  .log li{font-family:'JetBrains Mono',monospace;font-size:12.5px;background:var(--tint);border-radius:10px;padding:6px 12px}\n  .log li:first-child{background:var(--yellow-tint);font-weight:600}\n  .log .none{font-family:'Poppins',sans-serif;color:var(--gray)}\n\n  \/* ---------- Info ---------- *\/\n  .info{display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:24px;margin-top:24px}\n  @media (max-width:900px){.info{grid-template-columns:1fr}}\n  .info h2{font-weight:800;font-size:clamp(20px,2.6vw,26px);text-transform:uppercase;margin-bottom:10px}\n  .info h2 em{font-style:normal;color:var(--tan)}\n  .bullets{list-style:none;padding:0;margin:12px 0 0}\n  .bullets li{padding-left:28px;position:relative;margin-bottom:8px;font-weight:500}\n  .bullets li::before{content:\"\";position:absolute;left:0;top:7px;width:14px;height:14px;border-radius:50%;background:var(--yellow);box-shadow:0 0 0 4px var(--yellow-tint)}\n  table.big{width:100%;border-collapse:collapse;font-size:14px}\n  .big td{padding:9px 4px;border-bottom:1px solid var(--sky)}\n  .big td:last-child{text-align:right;font-family:'JetBrains Mono',monospace;font-weight:600}\n  .big td.word{font-family:'Poppins',sans-serif;font-weight:700;color:var(--green)}\n  .big tr:last-child td{border-bottom:none}\n  .tip{background:var(--yellow-tint);border-radius:16px;padding:14px 18px;border-left:6px solid var(--yellow)}\n  .tip strong{display:block;font-weight:700;text-transform:uppercase;font-size:12px;letter-spacing:.08em;color:var(--brown);margin-bottom:2px}\n  .tip + .tip{margin-top:12px}\n  footer{text-align:center;font-size:13px;color:var(--gray);padding:0 16px 32px}\n<\/style>\n<\/head>\n<body class=\"easy\">\n\n<header class=\"hero\">\n  <div class=\"bb l\"><svg viewBox=\"215 325 650 470\" aria-hidden=\"true\"><path d=\"M225 640 C240 628 255 650 265 648 C330 645 410 700 520 718 C610 728 690 705 725 688 C690 740 610 782 505 778 C400 774 300 745 262 705 C242 685 214 662 225 640 Z\" fill=\"#000\" fill-opacity=\".2\"\/><path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"#E6B94A\"\/> <path d=\"M268 578 C340 612 410 622 470 620 C565 616 655 562 712 505 C750 467 790 428 812 405 C790 470 730 560 640 610 C590 638 540 650 480 652 C400 652 322 622 266 592 Z\" fill=\"#CDA144\"\/> <path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <g fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linecap=\"butt\"> <path d=\"M302 618 C360 655 420 690 505 692 C620 694 730 610 812 518\"\/> <path d=\"M562 648 C660 610 760 530 815 418\"\/> <path d=\"M780 516 C795 485 808 452 818 420\"\/> <\/g> <path d=\"M808 405 L826 340 L848 345 L843 408 C835 420 818 422 808 405 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <path d=\"M249 555 C246 570 251 584 259 594 C269 588 277 580 282 572 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/><\/svg><\/div><div class=\"bb r\"><svg viewBox=\"215 325 650 470\" aria-hidden=\"true\"><path d=\"M225 640 C240 628 255 650 265 648 C330 645 410 700 520 718 C610 728 690 705 725 688 C690 740 610 782 505 778 C400 774 300 745 262 705 C242 685 214 662 225 640 Z\" fill=\"#000\" fill-opacity=\".2\"\/><path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"#E6B94A\"\/> <path d=\"M268 578 C340 612 410 622 470 620 C565 616 655 562 712 505 C750 467 790 428 812 405 C790 470 730 560 640 610 C590 638 540 650 480 652 C400 652 322 622 266 592 Z\" fill=\"#CDA144\"\/> <path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <g fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linecap=\"butt\"> <path d=\"M302 618 C360 655 420 690 505 692 C620 694 730 610 812 518\"\/> <path d=\"M562 648 C660 610 760 530 815 418\"\/> <path d=\"M780 516 C795 485 808 452 818 420\"\/> <\/g> <path d=\"M808 405 L826 340 L848 345 L843 408 C835 420 818 422 808 405 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <path d=\"M249 555 C246 570 251 584 259 594 C269 588 277 580 282 572 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/><\/svg><\/div>\n  <a class=\"eyebrow\" href=\"https:\/\/www.codemonkey.com\/interactive-cs-tools\" target=\"_top\">Interactive CS Tools<\/a>\n  <h1>Data Structure Playground<\/h1>\n  <p>Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time.<\/p>\n  <svg class=\"wave\" viewBox=\"0 0 1440 60\" preserveAspectRatio=\"none\" aria-hidden=\"true\"><path d=\"M0,32 C240,64 480,0 720,24 C960,48 1200,8 1440,30 L1440,60 L0,60 Z\" fill=\"#ffffff\"\/><\/svg>\n<\/header>\n\n<main class=\"wrap\">\n  <section class=\"card\" aria-label=\"Data structure playground\">\n    <div class=\"headrow\">\n      <div>\n        <span class=\"label\" id=\"dsLabel\">Data structure<\/span>\n        <div class=\"chips\" id=\"dsChips\" role=\"group\" aria-labelledby=\"dsLabel\"><\/div>\n      <\/div>\n      <div class=\"lvl\"><span class=\"label\">Level<\/span><div class=\"level\" role=\"group\" aria-label=\"Level\"><button type=\"button\" data-level=\"easy\" aria-pressed=\"true\">Easy<\/button><button type=\"button\" data-level=\"adv\" aria-pressed=\"false\">Advanced<\/button><\/div><div class=\"level-note\" id=\"levelNote\" data-easy=\"Plain words and simple speed ratings\" data-adv=\"Python code, Big-O and extra operations\"><\/div><\/div>\n    <\/div>\n\n    <div class=\"controls\">\n      <div>\n        <label class=\"label\" for=\"valIn\">Value<\/label>\n        <div class=\"valbox\">\n          <input type=\"number\" id=\"valIn\" min=\"0\" max=\"99\" inputmode=\"numeric\">\n          <button class=\"btn secondary icon\" type=\"button\" id=\"diceBtn\" title=\"Random value\" aria-label=\"Random value\">\n            <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M5 3h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2zm2.5 3A1.5 1.5 0 1 0 9 7.5 1.5 1.5 0 0 0 7.5 6zm9 0A1.5 1.5 0 1 0 18 7.5 1.5 1.5 0 0 0 16.5 6zM12 10.5A1.5 1.5 0 1 0 13.5 12 1.5 1.5 0 0 0 12 10.5zM7.5 15A1.5 1.5 0 1 0 9 16.5 1.5 1.5 0 0 0 7.5 15zm9 0a1.5 1.5 0 1 0 1.5 1.5 1.5 1.5 0 0 0-1.5-1.5z\"\/><\/svg>\n          <\/button>\n        <\/div>\n      <\/div>\n      <div>\n        <span class=\"label\">Operations<\/span>\n        <div class=\"ops\" id=\"ops\"><\/div>\n        <div class=\"ops-hint\">Green buttons marked <b>x<\/b> use the number in the Value box.<\/div>\n      <\/div>\n      <div class=\"speed\">\n        <label class=\"label\" for=\"speedIn\">Speed: <span class=\"val\" id=\"speedVal\">3<\/span><\/label>\n        <input type=\"range\" id=\"speedIn\" min=\"1\" max=\"5\" value=\"3\">\n      <\/div>\n    <\/div>\n\n    <div class=\"main-grid\">\n      <div>\n        <div class=\"stage\" id=\"stage\" aria-live=\"off\"><\/div>\n        <div class=\"legend\" id=\"legend\"><\/div>\n        <div class=\"status\" aria-live=\"polite\"><span class=\"dot\"><\/span><span id=\"status\"><\/span><\/div>\n      <\/div>\n      <aside class=\"side\">\n        <h3 id=\"codeTitle\">Python code<\/h3>\n        <div class=\"code\" id=\"code\"><\/div>\n        <div class=\"stats\">\n          <div class=\"stat\"><b id=\"sSize\">0<\/b><small>Size<\/small><\/div>\n          <div class=\"stat\"><b id=\"sKey\">&#8211;<\/b><small id=\"sKeyLbl\">Top<\/small><\/div>\n          <div class=\"stat\"><b id=\"sSteps\">0<\/b><small>Last steps<\/small><\/div>\n        <\/div>\n        <div class=\"log\">\n          <div class=\"log-head\"><h3>Operation log<\/h3><button class=\"linkbtn\" type=\"button\" id=\"logClear\">Clear<\/button><\/div>\n          <ol id=\"log\"><\/ol>\n        <\/div>\n      <\/aside>\n    <\/div>\n  <\/section>\n\n  <section class=\"info\">\n    <div class=\"card\">\n      <h2>What is a <em id=\"infoName\">stack<\/em>?<\/h2>\n      <p id=\"infoWhat\"><\/p>\n      <span class=\"label\" style=\"margin-top:14px\">Where you&#8217;ll find it<\/span>\n      <ul class=\"bullets\" id=\"infoUses\"><\/ul>\n    <\/div>\n    <div class=\"card\">\n      <h2 class=\"easy-only\">Fast or slow?<\/h2><h2 class=\"adv-only\">Speed (Big-O)<\/h2>\n      <table class=\"big\" id=\"infoBig\"><\/table>\n    <\/div>\n    <div class=\"card\">\n      <h2>Try this<\/h2>\n      <div class=\"tip\"><strong>Experiment<\/strong><span id=\"infoTip\"><\/span><\/div>\n      <div class=\"tip\"><strong>Discuss<\/strong><span id=\"infoAsk\"><\/span><\/div>\n    <\/div>\n  <\/section>\n<\/main>\n\n<footer>Tip: type a value and press <b>Enter<\/b> to run the first operation.<\/footer>\n\n<script>\n\nconst LEVEL=(function(){\n  let cur='easy'; const cbs=[];\n  try{\n    const q=new URLSearchParams(location.search).get('level');\n    if(q==='advanced'||q==='adv') cur='adv';\n    else if(q==='easy') cur='easy';\n    else { const s=localStorage.getItem('cm-cs-level'); if(s==='adv'||s==='easy') cur=s; }\n  }catch(e){}\n  function paint(){\n    document.querySelectorAll('.level button').forEach(b=>b.setAttribute('aria-pressed',b.dataset.level===cur));\n    const n=document.getElementById('levelNote'); if(n) n.textContent=n.getAttribute('data-'+cur)||'';\n    document.body.classList.toggle('adv',cur==='adv'); document.body.classList.toggle('easy',cur!=='adv');\n  }\n  function set(l){ cur=l; try{ localStorage.setItem('cm-cs-level',l); }catch(e){} paint(); cbs.forEach(f=>f(l)); }\n  document.querySelectorAll('.level button').forEach(b=>b.addEventListener('click',()=>{ if(b.dataset.level!==cur) set(b.dataset.level); }));\n  paint();\n  return {get:()=>cur, on:f=>cbs.push(f), set:set};\n})();\n\nconst LIMITS={stack:8, queue:10, list:8, bst:20};\nconst MAX_DEPTH=5;\n\nconst INFO={\n  stack:{name:'Stack', short:'stack',\n    what:'A stack works like a pile of plates. You can only add a plate to the top or take the top plate off. The last item in is the first item out, which is called LIFO.',\n    uses:['The Undo button in apps and games','The Back button in your web browser','How a program remembers which function to return to'],\n    big:[['Push','O(1)'],['Pop','O(1)'],['Peek','O(1)'],['Search for a value','O(n)']],\n    tip:'Push 1, 2 and 3, then pop three times. In what order do the values come out?',\n    ask:'Why is the Undo button a stack and not a queue?',\n    keyLbl:'Top', legend:[['var(--yellow)','Top item'],['var(--purple)','Peeking'],['var(--sky)','Other items']],\n    ops:[['push','Push',1],['pop','Pop',0],['peek','Peek',0],['clear','Clear',0]]},\n  queue:{name:'Queue', short:'queue',\n    what:'A queue works like a line at the lunch counter. New items join at the rear and leave from the front. The first item in is the first item out, which is called FIFO.',\n    uses:['Documents waiting for the printer','Players waiting to join an online game','Keyboard presses waiting to be processed'],\n    big:[['Enqueue','O(1)'],['Dequeue','O(1)'],['Peek at front','O(1)'],['Search for a value','O(n)']],\n    tip:'Enqueue 1, 2 and 3, then dequeue three times. Compare the order with the stack.',\n    ask:'Would a queue or a stack be fairer for a help desk? Why?',\n    keyLbl:'Front', legend:[['var(--yellow)','Front item'],['var(--purple)','Peeking'],['var(--sky)','Waiting']],\n    ops:[['enqueue','Enqueue',1],['dequeue','Dequeue',0],['peek','Peek',0],['clear','Clear',0]]},\n  list:{name:'Linked List', short:'linked list',\n    what:'A linked list is a chain of nodes. Each node holds a value and a pointer to the next node. To reach a node, you start at the head and follow the pointers one by one.',\n    uses:['A music playlist with Next buttons','Undo history in a text editor','Building other structures such as stacks and queues'],\n    big:[['Add to head','O(1)'],['Add to tail','O(n)'],['Search','O(n)'],['Remove a value','O(n)']],\n    tip:'Add a value to the head, then add one to the tail. Compare the Last steps counter for each.',\n    ask:'An array can jump straight to item 5. Why can\u2019t a linked list?',\n    keyLbl:'Head', legend:[['var(--yellow)','Visiting'],['var(--lime)','Found \/ new'],['var(--pink)','Removing']],\n    ops:[['head','Add to head',1],['tail','Add to tail',1],['search','Search',1],['remove','Remove',1],['clear','Clear',0]]},\n  bst:{name:'Binary Search Tree', short:'binary search tree',\n    what:'In a binary search tree, every node has up to two children. Smaller values go to the left and bigger values go to the right, so each comparison cuts the search in half.',\n    uses:['Looking up words in a dictionary app','Keeping a leaderboard in sorted order','Database indexes that find records fast'],\n    big:[['Search (balanced)','O(log n)'],['Insert (balanced)','O(log n)'],['Delete (balanced)','O(log n)'],['Any operation (worst case)','O(n)'],['Traversal','O(n)']],\n    tip:'Press Worst case. It inserts values in sorted order. What does the tree look like, and how many steps does a search take?',\n    ask:'Run an in-order traversal. What do you notice about the order of the values?',\n    keyLbl:'Height', legend:[['var(--yellow)','Comparing'],['var(--lime)','Found \/ new'],['var(--pink)','Deleting'],['var(--purple)','Successor \/ visiting']],\n    ops:[['insert','Insert',1],['search','Search',1],['delete','Delete',1],['in','In-order',0],['pre','Pre-order',0],['post','Post-order',0],['random','Random tree',0],['worst','Worst case',0],['clear','Clear',0]]}\n};\n\nconst CODE={\n  stack:{\n    push:['def push(stack, x):','    stack.append(x)    # add on top'],\n    pop:['def pop(stack):','    if not stack:','        raise IndexError(\"underflow\")','    return stack.pop() # remove top'],\n    peek:['def peek(stack):','    return stack[-1]   # look only'],\n    clear:['stack.clear()']},\n  queue:{\n    enqueue:['from collections import deque','queue = deque()','queue.append(x)     # join at rear'],\n    dequeue:['def dequeue(queue):','    if not queue:','        raise IndexError(\"empty\")','    return queue.popleft()  # front'],\n    peek:['front = queue[0]    # look only'],\n    clear:['queue.clear()']},\n  list:{\n    head:['node = Node(x)','node.next = head','head = node'],\n    tail:['node = Node(x)','if head is None: head = node','cur = head','while cur.next:','    cur = cur.next','cur.next = node'],\n    search:['cur = head','while cur:','    if cur.value == x:','        return cur','    cur = cur.next','return None'],\n    remove:['prev, cur = None, head','while cur and cur.value != x:','    prev, cur = cur, cur.next','if cur is None: return','if prev: prev.next = cur.next','else: head = cur.next'],\n    clear:['head = None']},\n  bst:{\n    insert:['def insert(node, x):','    if node is None:','        return Node(x)','    if x < node.value:','        node.left = insert(node.left, x)','    elif x > node.value:','        node.right = insert(node.right, x)','    return node'],\n    search:['def search(node, x):','    while node:','        if x == node.value:','            return node','        if x < node.value: node = node.left','        else: node = node.right','    return None'],\n    delete:['def delete(root, x):','    # 1. find the node','    # 2. leaf: just remove it','    # 3. one child: child moves up','    # 4. two children: copy the','    #    in-order successor here,','    #    then delete the successor'],\n    in:['def inorder(node):','    if node:','        inorder(node.left)','        visit(node)','        inorder(node.right)'],\n    pre:['def preorder(node):','    if node:','        visit(node)','        preorder(node.left)','        preorder(node.right)'],\n    post:['def postorder(node):','    if node:','        postorder(node.left)','        postorder(node.right)','        visit(node)'],\n    random:['for x in random_values:','    root = insert(root, x)'],\n    worst:['for x in [10, 20, 30, 40, 50, 60]:','    root = insert(root, x)'],\n    clear:['root = None']}\n};\n\nconst EASY_CODE={\n  stack:{\n    push:['To push x:','    put x on the top of the pile'],\n    pop:['To pop:','    if the pile is empty:','        stop! There is nothing to take','    take the top item off the pile'],\n    peek:['To peek:','    look at the top item, but leave it there'],\n    clear:['Take everything off the pile']},\n  queue:{\n    enqueue:['Start with a line of people','(it can be empty)','x joins at the back of the line'],\n    dequeue:['To dequeue:','    if the line is empty:','        stop! Nobody can leave','    the person at the front leaves'],\n    peek:['Look at who is at the front of the line'],\n    clear:['Everyone leaves the line']},\n  list:{\n    head:['Make a new node holding x','Point it at the old first node','Call the new node the head'],\n    tail:['Make a new node holding x','If the list is empty, x becomes the head','Otherwise, start at the head','While this node points to another node:','    follow the arrow to the next node','Point the last node at the new node'],\n    search:['Start at the head','While there is a node here:','    if it holds x:','        found it!','    if not, follow the arrow','Reached the end: x is not in the list'],\n    remove:['Start at the head','Walk along until you find x','    (remember the node just before it)','If you never find x, stop','Make the node before it skip over it','If x was the head, the next node becomes the head'],\n    clear:['Forget the head. The list is empty']},\n  bst:{\n    insert:['To insert x, start at the root:','    if this spot is empty:','        put x here!','    if x is smaller than this node:','        go left and try again','    if x is bigger:','        go right and try again','    if x is the same, skip it'],\n    search:['To find x, start at the root:','    while there is a node here:','        if it holds x:','            found it!','        if x is smaller, go left','        if x is bigger, go right','    fell off the tree: x is not here'],\n    delete:['To delete x:','    1. find the node','    2. no children: just remove it','    3. one child: the child moves up','    4. two children: find the next bigger','       value (the successor), copy it here,','       then remove the successor'],\n    in:['In-order visit:','    if there is a node here:','        first visit everything on the left','        then visit this node','        then visit everything on the right'],\n    pre:['Pre-order visit:','    if there is a node here:','        visit this node first','        then everything on the left','        then everything on the right'],\n    post:['Post-order visit:','    if there is a node here:','        first everything on the left','        then everything on the right','        visit this node last'],\n    random:['Pick some random values','and insert each one'],\n    worst:['Insert 10, 20, 30, 40, 50, 60','in that order'],\n    clear:['Remove every node']}\n};\nconst EASY_BIG={\n  stack:['Instant','Instant','Instant','Slower as the stack grows'],\n  queue:['Instant','Instant','Instant','Slower as the queue grows'],\n  list:['Instant','Slower as the list grows','Slower as the list grows','Slower as the list grows'],\n  bst:['Very fast (if the tree is bushy)','Very fast (if the tree is bushy)','Very fast (if the tree is bushy)','Slow if the tree is a long line','Visits every node once']\n};\nconst ADV_TEXT={\n  stack:{what:'A stack is a LIFO (last in, first out) collection. In Python, a list works as a stack: append() pushes and pop() removes from the end, both in O(1) amortized time.',\n         tip:'Use a stack to check if brackets are balanced: push every \"(\" and pop on every \")\". What should happen with \"(()\"?',\n         ask:'Recursion uses the call stack. What happens when a recursive function never stops (stack overflow)?'},\n  queue:{what:'A queue is a FIFO (first in, first out) collection. Python lists are slow at removing from the front (O(n)), so collections.deque is used for O(1) appends and pops at both ends.',\n         tip:'Breadth-first search uses a queue. Why does a queue make it explore nodes level by level?',\n         ask:'Why is list.pop(0) O(n) in Python, while deque.popleft() is O(1)?'},\n  list:{what:'A singly linked list stores nodes that each hold a value and a reference to the next node. Inserting at the head is O(1), but reaching position k means following k pointers, so indexing is O(n).',\n        tip:'Compare \"Add to head\" and \"Add to tail\". How could keeping a tail pointer make adding to the tail O(1)?',\n        ask:'Arrays use contiguous memory and linked lists use pointers. Which one is friendlier to the CPU cache, and why?'},\n  bst:{what:'A binary search tree keeps the invariant left < node < right for every node. Search, insert and delete follow one path from the root, so they cost O(h), where h is the height: about log2 n when balanced, but n in the worst case.',\n       tip:'Press Worst case and search for 60. Then build a balanced tree from the same values. How many comparisons does each take?',\n       ask:'Self-balancing trees (AVL, red-black) keep h = O(log n). What operation do they add to stay balanced?'}\n};\n\n\/\/ ---------- state ----------\nlet ds='stack', busy=false, steps=0, nid=1;\nlet stack=[], queue=[], list=[], root=null;\nlet hl={}, fresh=null, trav=[], hotEdges={};\nconst logs={stack:[], queue:[], list:[], bst:[]};\nconst codeState={op:null, line:-1};\n\nconst $=id=>document.getElementById(id);\nconst sleep=ms=>new Promise(r=>setTimeout(r,ms));\nconst delay=()=>[1100,800,550,350,200][+$('speedIn').value-1];\nconst mk=v=>({v:v, id:'n'+(nid++)});\nconst mkB=v=>({v:v, id:'n'+(nid++), l:null, r:null});\nconst rnd=()=>1+Math.floor(Math.random()*99);\n\nfunction say(t){ $('status').textContent=t; }\nfunction addLog(t){ logs[ds].unshift(t); if(logs[ds].length>12) logs[ds].pop(); }\nfunction shake(){ const s=$('stage'); s.classList.remove('shake'); void s.offsetWidth; s.classList.add('shake'); }\nfunction code(op,line){ codeState.op=op; codeState.line=(line===undefined)?-1:line; renderCode(); }\n\nfunction renderCode(){\n  const box=$('code'); box.innerHTML='';\n  const op=codeState.op;\n  const adv=LEVEL.get()==='adv';\n  const lines=(adv?CODE[ds][op]:EASY_CODE[ds][op])||[];\n  box.classList.toggle('plain',!adv);\n  $('codeTitle').textContent=adv?'Python code':'What happens';\n  const t=document.createElement('div'); t.className='ttl'; t.textContent=INFO[ds].name+' \u00b7 '+opLabel(op); box.appendChild(t);\n  lines.forEach((l,i)=>{ const d=document.createElement('div'); d.className='ln'+(i===codeState.line?' active':''); d.textContent=l; box.appendChild(d); });\n}\nfunction opLabel(op){ const o=INFO[ds].ops.find(x=>x[0]===op); return o?o[1]:''; }\n\n\/\/ ---------- rendering ----------\nfunction cls(it,base){ let c=base; if(hl[it.id]) c+=' '+hl[it.id]; if(fresh===it.id) c+=' enter'; return c; }\n\nfunction stackHTML(){\n  let s='<div class=\"stack-wrap\"><div class=\"stack-col\">';\n  if(stack.length===0) s+='<div class=\"placeholder\">Empty stack<\/div>';\n  stack.forEach((it,i)=>{\n    const top=i===stack.length-1;\n    s+='<div class=\"'+cls(it,'item'+(top?' top':''))+'\">'+it.v+(top?'<span class=\"tag\">Top<\/span>':'')+'<\/div>';\n  });\n  return s+'<\/div><div class=\"stack-base\"><\/div><\/div>';\n}\nfunction queueHTML(){\n  let s='<div class=\"queue-wrap\"><div class=\"q-end\"><b>\u2190<\/b>out<\/div><div class=\"queue-row\">';\n  if(queue.length===0) s+='<div class=\"empty-msg\">Empty queue<\/div>';\n  queue.forEach((it,i)=>{\n    const front=i===0, rear=i===queue.length-1;\n    let tag=front?(rear?'Front \/ Rear':'Front'):(rear?'Rear':'');\n    s+='<div class=\"'+cls(it,'qitem'+(front?' front':''))+'\">'+it.v+(tag?'<span class=\"tag\">'+tag+'<\/span>':'')+'<\/div>';\n  });\n  return s+'<\/div><div class=\"q-end\"><b>\u2190<\/b>in<\/div><\/div>';\n}\nfunction listHTML(){\n  let s='<div class=\"ll\"><span class=\"headptr\">HEAD<\/span><span class=\"arr\"><\/span>';\n  list.forEach(it=>{ s+='<div class=\"'+cls(it,'node')+'\"><span class=\"nv\">'+it.v+'<\/span><span class=\"np\"><\/span><\/div><span class=\"arr\"><\/span>'; });\n  return s+'<span class=\"nullbox\">None<\/span><\/div>';\n}\nfunction layout(){\n  const out=[]; let i=0;\n  (function go(n,d){ if(!n) return; go(n.l,d+1); out.push({n:n,i:i++,d:d}); go(n.r,d+1); })(root,0);\n  return out;\n}\nfunction height(n){ return n?1+Math.max(height(n.l),height(n.r)):0; }\nfunction count(n){ return n?1+count(n.l)+count(n.r):0; }\nfunction bstHTML(){\n  if(!root) return '<div class=\"empty-msg\">The tree is empty. Insert a value to plant the root.<\/div>';\n  const L=layout(), N=L.length, pos={};\n  L.forEach(o=>{ pos[o.n.id]={x:40+(o.i+0.5)*(680\/N), y:40+o.d*66}; });\n  let e='', nodes='';\n  L.forEach(o=>{\n    const p=pos[o.n.id];\n    [o.n.l,o.n.r].forEach(ch=>{ if(ch){ const q=pos[ch.id]; e+='<line x1=\"'+p.x+'\" y1=\"'+p.y+'\" x2=\"'+q.x+'\" y2=\"'+q.y+'\" class=\"edge'+(hotEdges[ch.id]?' hot':'')+'\"\/>'; } });\n    nodes+='<g class=\"'+cls(o.n,'bn')+'\"><circle cx=\"'+p.x+'\" cy=\"'+p.y+'\" r=\"21\"\/><text x=\"'+p.x+'\" y=\"'+(p.y+5)+'\">'+o.n.v+'<\/text><\/g>';\n  });\n  let s='<svg class=\"tree\" viewBox=\"0 0 760 400\" role=\"img\" aria-label=\"Binary search tree\">'+e+nodes+'<\/svg>';\n  if(trav.length){ s+='<div class=\"trav\"><span class=\"tag\">Visit order<\/span>'+trav.map(v=>'<span>'+v+'<\/span>').join('')+'<\/div>'; }\n  return s;\n}\n\nfunction render(){\n  const st=$('stage');\n  st.classList.remove('ds-stack','ds-queue','ds-list','ds-bst');\n  st.classList.add('ds-'+ds);\n  st.innerHTML= ds==='stack'?stackHTML():(ds==='queue'?queueHTML():(ds==='list'?listHTML():bstHTML()));\n  fresh=null;\n  const size= ds==='stack'?stack.length:(ds==='queue'?queue.length:(ds==='list'?list.length:count(root)));\n  let key='-';\n  if(ds==='stack') key=stack.length?stack[stack.length-1].v:'-';\n  if(ds==='queue') key=queue.length?queue[0].v:'-';\n  if(ds==='list') key=list.length?list[0].v:'-';\n  if(ds==='bst') key=height(root);\n  $('sSize').textContent=size; $('sKey').textContent=key; $('sSteps').textContent=steps;\n  const lg=logs[ds];\n  $('log').innerHTML= lg.length ? lg.map(t=>'<li>'+t+'<\/li>').join('') : '<li class=\"none\">Nothing yet. Try an operation!<\/li>';\n  $('logClear').disabled= lg.length===0 ? true : busy;\n}\n\nfunction renderOps(){\n  const box=$('ops'); box.innerHTML='';\n  INFO[ds].ops.forEach((o,i)=>{\n    if(LEVEL.get()!=='adv' ? (o[0]==='pre' || o[0]==='post') : false) return;\n    const b=document.createElement('button');\n    b.type='button';\n    b.className='btn '+(o[2]?'arg':'secondary');\n    if(o[2]) b.title=o[1]+' the value in the box';\n    b.textContent=o[1];\n    b.dataset.op=o[0];\n    b.addEventListener('click',()=>doOp(o[0]));\n    box.appendChild(b);\n  });\n}\nfunction setBusy(v){ busy=v; document.querySelectorAll('#ops .btn, #dsChips .chip, #diceBtn, .level button').forEach(b=>{ b.disabled=v; }); }\n\nfunction selectDS(key){\n  ds=key; hl={}; trav=[]; hotEdges={}; steps=0;\n  document.querySelectorAll('#dsChips .chip').forEach(c=>c.setAttribute('aria-pressed',c.dataset.key===key));\n  const I=INFO[key];\n  const adv=LEVEL.get()==='adv';\n  $('infoName').textContent=I.short; $('infoWhat').textContent=adv?ADV_TEXT[key].what:I.what;\n  $('infoUses').innerHTML=I.uses.map(u=>'<li>'+u+'<\/li>').join('');\n  $('infoBig').innerHTML=I.big.map((r,i)=>'<tr><td>'+r[0]+'<\/td><td'+(adv?'':' class=\"word\"')+'>'+(adv?r[1]:EASY_BIG[key][i])+'<\/td><\/tr>').join('');\n  $('infoTip').textContent=adv?ADV_TEXT[key].tip:I.tip; $('infoAsk').textContent=adv?ADV_TEXT[key].ask:I.ask;\n  $('sKeyLbl').textContent=I.keyLbl;\n  $('legend').innerHTML=I.legend.map(l=>'<span><i style=\"background:'+l[0]+'\"><\/i>'+l[1]+'<\/span>').join('');\n  renderOps(); code(I.ops[0][0]); render();\n  say('Type a value and choose an operation to see the '+I.short+' in action.');\n}\n\n\/\/ ---------- operations ----------\nfunction readVal(){\n  const el=$('valIn'); let v=parseInt(el.value,10);\n  if(isNaN(v)){ v=rnd(); el.value=v; }\n  v=Math.max(0,Math.min(99,v)); el.value=v;\n  return v;\n}\nfunction nextVal(){ $('valIn').value=rnd(); }\n\nasync function doOp(op){\n  if(busy) return;\n  const o=INFO[ds].ops.find(x=>x[0]===op);\n  const v=o[2]?readVal():null;\n  setBusy(true); trav=[]; hotEdges={};\n  try{ await OPS[ds][op](v); }\n  finally{ hl={}; setBusy(false); render(); }\n}\n\nconst OPS={\n  stack:{\n    push:async v=>{\n      code('push',1);\n      if(stack.length>=LIMITS.stack){ code('push'); say('Stack overflow! This stack holds '+LIMITS.stack+' items. Pop one first.'); shake(); return; }\n      const it=mk(v); stack.push(it); fresh=it.id; steps=1;\n      addLog('push('+v+')'); say('Pushed '+v+' onto the top. It is now the first item that will come out.'); render(); nextVal();\n      await sleep(400);\n    },\n    pop:async ()=>{\n      if(stack.length===0){ code('pop',2); say('Stack underflow! There is nothing to pop.'); shake(); steps=0; return; }\n      code('pop',3);\n      const it=stack[stack.length-1]; hl[it.id]='leave'; render(); await sleep(420);\n      stack.pop(); steps=1; addLog('pop() \u2192 '+it.v); say('Popped '+it.v+' off the top. Last in, first out!');\n    },\n    peek:async ()=>{\n      if(stack.length===0){ code('peek'); say('The stack is empty, so there is nothing to peek at.'); shake(); return; }\n      code('peek',1);\n      const it=stack[stack.length-1]; hl[it.id]='peek'; render(); steps=1;\n      addLog('peek() \u2192 '+it.v); say('The top item is '+it.v+'. Peeking looks without removing it.');\n      await sleep(Math.max(900,delay()));\n    },\n    clear:async ()=>{ code('clear',0); stack=[]; steps=0; addLog('clear()'); say('The stack is now empty.'); }\n  },\n  queue:{\n    enqueue:async v=>{\n      code('enqueue',2);\n      if(queue.length>=LIMITS.queue){ say('The queue is full ('+LIMITS.queue+' items). Dequeue one first.'); shake(); return; }\n      const it=mk(v); queue.push(it); fresh=it.id; steps=1;\n      addLog('enqueue('+v+')'); say(v+' joined the rear of the queue.'); render(); nextVal();\n      await sleep(400);\n    },\n    dequeue:async ()=>{\n      if(queue.length===0){ code('dequeue',2); say('The queue is empty, so nobody can leave.'); shake(); steps=0; return; }\n      code('dequeue',3);\n      const it=queue[0]; hl[it.id]='leave'; render(); await sleep(420);\n      queue.shift(); steps=1; addLog('dequeue() \u2192 '+it.v); say(it.v+' left from the front. First in, first out!');\n    },\n    peek:async ()=>{\n      if(queue.length===0){ code('peek'); say('The queue is empty, so there is nothing to peek at.'); shake(); return; }\n      code('peek',0);\n      const it=queue[0]; hl[it.id]='peek'; render(); steps=1;\n      addLog('peek() \u2192 '+it.v); say('The front item is '+it.v+'. It will be the next to leave.');\n      await sleep(Math.max(900,delay()));\n    },\n    clear:async ()=>{ code('clear',0); queue=[]; steps=0; addLog('clear()'); say('The queue is now empty.'); }\n  },\n  list:{\n    head:async v=>{\n      if(list.length>=LIMITS.list){ code('head'); say('This list holds '+LIMITS.list+' nodes on screen. Remove one first.'); shake(); return; }\n      const it=mk(v);\n      code('head',0); say('Create a new node holding '+v+'.'); await sleep(delay()\/2);\n      code('head',1); list.unshift(it); fresh=it.id; hl[it.id]='new'; steps=1;\n      say('Point the new node at the old head...'); render(); await sleep(delay());\n      code('head',2); say('...and make it the new head. Done in just 1 step, no matter how long the list is.');\n      addLog('add_head('+v+')'); nextVal(); await sleep(delay());\n    },\n    tail:async v=>{\n      if(list.length>=LIMITS.list){ code('tail'); say('This list holds '+LIMITS.list+' nodes on screen. Remove one first.'); shake(); return; }\n      const it=mk(v);\n      if(list.length===0){\n        code('tail',1); list.push(it); fresh=it.id; hl[it.id]='new'; steps=1;\n        say('The list was empty, so '+v+' becomes the head.'); addLog('add_tail('+v+')'); render(); nextVal(); await sleep(delay()); return;\n      }\n      steps=0;\n      for(let i=0;i<list.length;i++){\n        hl={}; hl[list[i].id]='cur'; steps++;\n        code('tail', i===0?2:4);\n        say(i===list.length-1?'Node '+list[i].v+' points to None, so this is the tail.':'At node '+list[i].v+'. It has a next node, so keep walking.');\n        render(); await sleep(delay());\n      }\n      code('tail',5); hl={}; list.push(it); fresh=it.id; hl[it.id]='new';\n      say('Walked through '+steps+' node'+(steps===1?'':'s')+' to reach the tail, then linked '+v+' on the end.');\n      addLog('add_tail('+v+')'); render(); nextVal(); await sleep(delay());\n    },\n    search:async v=>{\n      steps=0;\n      for(let i=0;i<list.length;i++){\n        hl={}; hl[list[i].id]='cur'; steps++; code('search',2);\n        say('Step '+steps+': is '+list[i].v+' equal to '+v+'?'); render(); await sleep(delay());\n        if(list[i].v===v){ hl[list[i].id]='found'; code('search',3); say('Found '+v+' after '+steps+' step'+(steps===1?'':'s')+'.'); addLog('search('+v+') \u2192 found'); render(); await sleep(Math.max(900,delay())); return; }\n        code('search',4); say('No, follow the pointer to the next node.'); render(); await sleep(delay()\/2);\n      }\n      code('search',5); say(v+' is not in the list. We checked all '+steps+' node'+(steps===1?'':'s')+'.'); addLog('search('+v+') \u2192 None');\n      if(list.length===0) say('The list is empty, so '+v+' cannot be in it.');\n      await sleep(delay());\n    },\n    remove:async v=>{\n      steps=0;\n      for(let i=0;i<list.length;i++){\n        hl={}; hl[list[i].id]='cur'; steps++; code('remove',1);\n        say('Step '+steps+': is this node '+v+'?'); render(); await sleep(delay());\n        if(list[i].v===v){\n          const it=list[i];\n          code('remove', i===0?5:4);\n          hl[it.id]='del';\n          say(i===0?'Found it at the head. The head now points to the next node.':'Found it! The previous node now skips over it.');\n          render(); await sleep(delay());\n          hl[it.id]='del leave'; render(); await sleep(420);\n          list.splice(i,1); addLog('remove('+v+')'); return;\n        }\n        code('remove',2);\n      }\n      code('remove',3); say(v+' is not in the list, so nothing was removed.'); addLog('remove('+v+') \u2192 not found');\n      if(list.length===0) say('The list is empty, so there is nothing to remove.');\n      await sleep(delay());\n    },\n    clear:async ()=>{ code('clear',0); list=[]; steps=0; addLog('clear()'); say('head = None. The whole list is gone.'); }\n  },\n  bst:{\n    insert:async v=>{\n      if(count(root)>=LIMITS.bst){ code('insert'); say('The tree holds '+LIMITS.bst+' nodes on screen. Delete one first.'); shake(); return; }\n      steps=0;\n      if(!root){ code('insert',2); root=mkB(v); fresh=root.id; steps=1; say('The tree was empty, so '+v+' becomes the root.'); addLog('insert('+v+')'); render(); nextVal(); await sleep(delay()); return; }\n      let cur=root, d=0;\n      while(true){\n        steps++; hl[cur.id]='path'; code('insert',3);\n        say('Compare '+v+' with '+cur.v+'.'); render(); await sleep(delay());\n        if(v===cur.v){ hl[cur.id]='found'; code('insert',7); say(v+' is already in the tree. A BST stores each value only once.'); addLog('insert('+v+') \u2192 duplicate'); render(); await sleep(Math.max(900,delay())); return; }\n        const left=v<cur.v;\n        code('insert', left?4:6);\n        say(v+(left?' is smaller than ':' is bigger than ')+cur.v+', so go '+(left?'left.':'right.'));\n        render(); await sleep(delay());\n        const next=left?cur.l:cur.r;\n        if(!next){\n          if(d+1>MAX_DEPTH){ say('That branch is too deep to draw. Try a different value, or Clear and build a more balanced tree.'); shake(); return; }\n          const n=mkB(v); if(left) cur.l=n; else cur.r=n;\n          fresh=n.id; hl[n.id]='new'; hotEdges[n.id]=true; code('insert',2);\n          say('Empty spot! '+v+' becomes the '+(left?'left':'right')+' child of '+cur.v+'. That took '+steps+' comparison'+(steps===1?'':'s')+'.');\n          addLog('insert('+v+')'); render(); nextVal(); await sleep(Math.max(900,delay()));\n          return;\n        }\n        hotEdges[next.id]=true; cur=next; d++;\n      }\n    },\n    search:async v=>{\n      steps=0; let cur=root;\n      if(!cur){ code('search',6); say('The tree is empty, so '+v+' cannot be in it.'); return; }\n      while(cur){\n        steps++; hl[cur.id]='path'; code('search',2);\n        say('Compare '+v+' with '+cur.v+'.'); render(); await sleep(delay());\n        if(v===cur.v){ hl[cur.id]='found'; code('search',3); say('Found '+v+' in '+steps+' step'+(steps===1?'':'s')+'. A list might need up to '+count(root)+'.'); addLog('search('+v+') \u2192 found'); render(); await sleep(Math.max(1000,delay())); return; }\n        const left=v<cur.v; code('search', left?4:5);\n        say(v+(left?' is smaller, so go left.':' is bigger, so go right.'));\n        const next=left?cur.l:cur.r;\n        if(next) hotEdges[next.id]=true;\n        render(); await sleep(delay());\n        cur=next;\n      }\n      code('search',6); say('We fell off the tree after '+steps+' step'+(steps===1?'':'s')+', so '+v+' is not here.'); addLog('search('+v+') \u2192 None'); await sleep(delay());\n    },\n    delete:async v=>{\n      steps=0; let cur=root, par=null, dir=null;\n      code('delete',1);\n      while(cur){\n        steps++; hl[cur.id]='path';\n        say('Looking for '+v+': compare with '+cur.v+'.'); render(); await sleep(delay());\n        if(v===cur.v) break;\n        par=cur; dir=v<cur.v?'l':'r';\n        if(cur[dir]) hotEdges[cur[dir].id]=true;\n        cur=cur[dir];\n      }\n      if(!cur){ say(v+' is not in the tree, so nothing was deleted.'); addLog('delete('+v+') \u2192 not found'); if(!root) say('The tree is empty.'); await sleep(delay()); return; }\n      hl[cur.id]='del'; render();\n      const two = cur.l ? !!cur.r : false;\n      if(two){\n        code('delete',4);\n        let sp=cur, s=cur.r; hl[s.id]='succ';\n        say(v+' has two children. Find its in-order successor: step right once, then all the way left.'); render(); await sleep(delay());\n        while(s.l){ sp=s; s=s.l; hl[s.id]='succ'; steps++; render(); await sleep(delay()); }\n        code('delete',5);\n        say('The successor is '+s.v+', the smallest value bigger than '+v+'. Copy it into '+v+'\u2019s spot.'); render(); await sleep(Math.max(1000,delay()));\n        hl[s.id]='del leave'; render(); await sleep(420);\n        cur.v=s.v;\n        if(sp===cur) sp.r=s.r; else sp.l=s.r;\n        hl={}; hl[cur.id]='found'; code('delete',6);\n        say('Done! '+s.v+' replaced '+v+', and the old successor node was removed. The tree is still in order.');\n        render(); await sleep(Math.max(1000,delay()));\n      } else {\n        const child=cur.l?cur.l:cur.r;\n        code('delete', child?3:2);\n        say(child?(v+' has one child, so that child ('+child.v+') moves up to take its place.'):(v+' is a leaf, so we can simply remove it.'));\n        render(); await sleep(delay());\n        hl[cur.id]='del leave'; render(); await sleep(420);\n        if(!par) root=child; else par[dir]=child;\n      }\n      addLog('delete('+v+')');\n    },\n    in:async ()=>traverse('in'),\n    pre:async ()=>traverse('pre'),\n    post:async ()=>traverse('post'),\n    random:async ()=>{\n      code('random',1); root=null; steps=0;\n      let tries=0;\n      while(count(root)<9){ if(tries>200) break; tries++; insertQuiet(rnd()); }\n      addLog('random tree'); say('A random tree with '+count(root)+' nodes. Try searching for a value!');\n    },\n    worst:async ()=>{\n      code('worst',1); root=null; steps=0;\n      [10,20,30,40,50,60].forEach(insertQuiet);\n      addLog('insert 10..60 in order'); say('Sorted input makes every node go right. The tree turns into a list, so searching takes up to n steps instead of log n.');\n    },\n    clear:async ()=>{ code('clear',0); root=null; steps=0; addLog('clear()'); say('The tree is empty.'); }\n  }\n};\n\nfunction insertQuiet(v){\n  if(!root){ root=mkB(v); return true; }\n  let cur=root, d=0;\n  while(true){\n    if(v===cur.v) return false;\n    const k=v<cur.v?'l':'r';\n    if(!cur[k]){ if(d+1>MAX_DEPTH) return false; cur[k]=mkB(v); return true; }\n    cur=cur[k]; d++;\n  }\n}\n\nasync function traverse(kind){\n  if(!root){ code(kind); say('The tree is empty, so there is nothing to visit.'); return; }\n  const order=[];\n  (function go(n){ if(!n) return; if(kind==='pre') order.push(n); go(n.l); if(kind==='in') order.push(n); go(n.r); if(kind==='post') order.push(n); })(root);\n  trav=[]; hl={}; steps=0;\n  const name={in:'In-order',pre:'Pre-order',post:'Post-order'}[kind];\n  const rule={in:'left subtree, node, right subtree',pre:'node, left subtree, right subtree',post:'left subtree, right subtree, node'}[kind];\n  code(kind,1); say(name+' traversal visits: '+rule+'.'); render(); await sleep(delay());\n  for(const n of order){\n    Object.keys(hl).forEach(k=>{ if(hl[k]==='visit') hl[k]='done'; });\n    hl[n.id]='visit'; trav.push(n.v); steps++;\n    code(kind, kind==='in'?3:(kind==='pre'?2:4));\n    say('Visit '+n.v+'.'); render(); await sleep(delay());\n  }\n  say(name+': '+trav.join(', ')+(kind==='in'?'. In-order always comes out sorted!':'.'));\n  addLog(kind+'order() \u2192 '+trav.join(' '));\n  Object.keys(hl).forEach(k=>{ hl[k]='done'; });\n  render(); await sleep(400);\n}\n\n\/\/ ---------- setup ----------\nObject.keys(INFO).forEach(k=>{\n  const b=document.createElement('button');\n  b.type='button'; b.className='chip'; b.dataset.key=k; b.textContent=INFO[k].name;\n  b.addEventListener('click',()=>{ if(!busy) selectDS(k); });\n  $('dsChips').appendChild(b);\n});\n$('logClear').addEventListener('click',()=>{ if(busy) return; logs[ds]=[]; render(); });\nLEVEL.on(()=>{ if(busy) return; const op=codeState.op; selectDS(ds); if(op) code(op); });\n$('diceBtn').addEventListener('click',()=>{ nextVal(); $('valIn').focus(); });\n$('speedIn').addEventListener('input',e=>{ $('speedVal').textContent=e.target.value; });\n$('valIn').addEventListener('keydown',e=>{ if(e.key==='Enter'){ e.preventDefault(); const first=INFO[ds].ops[0]; doOp(first[0]); } });\n\n[12,27,5].forEach(v=>stack.push(mk(v)));\n[8,15,23].forEach(v=>queue.push(mk(v)));\n[4,9,16].forEach(v=>list.push(mk(v)));\n[50,30,70,20,40,60,80].forEach(insertQuiet);\nnextVal();\nselectDS('stack');\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Data Structures&#8221;<\/span><\/a><\/p>","protected":false},"author":55,"featured_media":0,"parent":31237,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-31065","page","type-page","status-publish","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO Pro 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO Pro (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"ru_RU\" \/>\n\t\t<meta property=\"og:site_name\" content=\"CodeMonkey -\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Data Structures - CodeMonkey\" \/>\n\t\t<meta property=\"og:description\" content=\"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-10-08T11:49:47+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-10-29T16:51:56+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Data Structures - CodeMonkey\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/#listItem\",\"name\":\"Free Teacher Tools for Computer Science\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/#listItem\",\"position\":2,\"name\":\"Free Teacher Tools for Computer Science\",\"item\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/#listItem\",\"name\":\"Data Structures\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/#listItem\",\"position\":3,\"name\":\"Data Structures\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/#listItem\",\"name\":\"Free Teacher Tools for Computer Science\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/#organization\",\"name\":\"CodeMonkey\",\"url\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/d3sujgifhk94se.cloudfront.net\\\/wp-content\\\/uploads\\\/2020\\\/06\\\/21143425\\\/codemonkey_logo.png\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/#organizationLogo\",\"width\":200,\"height\":31,\"caption\":\"Codemonkey Coding for Kids\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/#organizationLogo\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/#webpage\",\"url\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/\",\"name\":\"Data Structures - CodeMonkey\",\"description\":\"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top\",\"inLanguage\":\"ru-RU\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/interactive-cs-tools\\\/data-structures\\\/#breadcrumblist\"},\"datePublished\":\"2026-10-08T11:49:47+00:00\",\"dateModified\":\"2026-10-29T16:51:56+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/#website\",\"url\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/\",\"name\":\"CodeMonkey\",\"inLanguage\":\"ru-RU\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/ru\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO Pro -->\r\n\t\t<title>Data Structures - CodeMonkey<\/title>\n\n","aioseo_head_json":{"title":"Data Structures - CodeMonkey","description":"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top","canonical_url":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/ru\/#listItem","position":1,"name":"Home","item":"https:\/\/www.codemonkey.com\/ru\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/#listItem","name":"Free Teacher Tools for Computer Science"}},{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/#listItem","position":2,"name":"Free Teacher Tools for Computer Science","item":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/#listItem","name":"Data Structures"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/ru\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/#listItem","position":3,"name":"Data Structures","previousItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/#listItem","name":"Free Teacher Tools for Computer Science"}}]},{"@type":"Organization","@id":"https:\/\/www.codemonkey.com\/ru\/#organization","name":"CodeMonkey","url":"https:\/\/www.codemonkey.com\/ru\/","logo":{"@type":"ImageObject","url":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/#organizationLogo","width":200,"height":31,"caption":"Codemonkey Coding for Kids"},"image":{"@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/#organizationLogo"}},{"@type":"WebPage","@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/#webpage","url":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/","name":"Data Structures - CodeMonkey","description":"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top","inLanguage":"ru-RU","isPartOf":{"@id":"https:\/\/www.codemonkey.com\/ru\/#website"},"breadcrumb":{"@id":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/#breadcrumblist"},"datePublished":"2026-10-08T11:49:47+00:00","dateModified":"2026-10-29T16:51:56+00:00"},{"@type":"WebSite","@id":"https:\/\/www.codemonkey.com\/ru\/#website","url":"https:\/\/www.codemonkey.com\/ru\/","name":"CodeMonkey","inLanguage":"ru-RU","publisher":{"@id":"https:\/\/www.codemonkey.com\/ru\/#organization"}}]},"og:locale":"ru_RU","og:site_name":"CodeMonkey -","og:type":"article","og:title":"Data Structures - CodeMonkey","og:description":"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top","og:url":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/","og:image":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png","og:image:secure_url":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png","article:published_time":"2026-10-08T11:49:47+00:00","article:modified_time":"2026-10-29T16:51:56+00:00","twitter:card":"summary_large_image","twitter:title":"Data Structures - CodeMonkey","twitter:description":"Data Structure Playground Interactive CS Tools Data Structure Playground Push, pop, link and branch. See how stacks, queues, linked lists and binary search trees really store your data, one step at a time. Data structure LevelEasyAdvanced Value Operations Green buttons marked x use the number in the Value box. Speed: 3 Python code 0Size -Top","twitter:image":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png"},"aioseo_meta_data":{"post_id":"31065","title":null,"description":null,"keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"WebPage","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"limit_modified_date":false,"open_ai":null,"created":"2026-10-08 11:48:15","updated":"2026-10-29 16:52:34","focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"breadcrumb_settings":null,"seo_analyzer_scan_date":"2026-10-29 16:52:34"},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t<a href=\"https:\/\/www.codemonkey.com\/ru\/\" title=\"Home\">Home<\/a>\n<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t<a href=\"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/\" title=\"Free Teacher Tools for Computer Science\">Free Teacher Tools for Computer Science<\/a>\n<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\tData Structures\n<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.codemonkey.com\/ru\/"},{"label":"Free Teacher Tools for Computer Science","link":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/"},{"label":"Data Structures","link":"https:\/\/www.codemonkey.com\/ru\/interactive-cs-tools\/data-structures\/"}],"_links":{"self":[{"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/pages\/31065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/comments?post=31065"}],"version-history":[{"count":2,"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/pages\/31065\/revisions"}],"predecessor-version":[{"id":31229,"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/pages\/31065\/revisions\/31229"}],"up":[{"embeddable":true,"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/pages\/31237"}],"wp:attachment":[{"href":"https:\/\/www.codemonkey.com\/ru\/wp-json\/wp\/v2\/media?parent=31065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}