<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Umer Akram</title>
    <description>The latest articles on DEV Community by Umer Akram (@umer1100).</description>
    <link>https://dev.to/umer1100</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4215560%2F95b5a3a7-f93d-4dca-812e-2e8e040edb30.jpg</url>
      <title>DEV Community: Umer Akram</title>
      <link>https://dev.to/umer1100</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/umer1100"/>
    <language>en</language>
    <item>
      <title>AVL Tree Rotations Explained Step by Step (With All 4 Cases)</title>
      <dc:creator>Umer Akram</dc:creator>
      <pubDate>Thu, 29 Oct 2026 15:03:36 +0000</pubDate>
      <link>https://dev.to/umer1100/avl-tree-rotations-explained-step-by-step-with-all-4-cases-4n5i</link>
      <guid>https://dev.to/umer1100/avl-tree-rotations-explained-step-by-step-with-all-4-cases-4n5i</guid>
      <description>&lt;p&gt;AVL rotations are one of those topics that make sense in a lecture and fall apart the moment you try to do one on paper. Which node do you rotate? Left or right? Why do some cases need &lt;em&gt;two&lt;/em&gt; rotations?&lt;/p&gt;

&lt;p&gt;This post walks through all four cases one insert at a time, with the balance factors written out, so you can see exactly &lt;em&gt;why&lt;/em&gt; each rotation happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AVL trees rotate at all
&lt;/h2&gt;

&lt;p&gt;A plain binary search tree (BST) can become a linked list. Insert &lt;code&gt;10, 20, 30, 40, 50&lt;/code&gt; in order and every node hangs off the right of the previous one. Search becomes &lt;strong&gt;O(n)&lt;/strong&gt; instead of &lt;strong&gt;O(log n)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;AVL tree&lt;/strong&gt; prevents this by keeping every node balanced. After each insert or delete it checks the &lt;strong&gt;balance factor&lt;/strong&gt; of each node on the path back up to the root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;balance factor = height(left subtree) − height(right subtree)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule is simple: every node's balance factor must be &lt;strong&gt;−1, 0 or +1&lt;/strong&gt;. When a node hits &lt;strong&gt;+2&lt;/strong&gt; or &lt;strong&gt;−2&lt;/strong&gt;, it's unbalanced, and a &lt;strong&gt;rotation&lt;/strong&gt; fixes it.&lt;/p&gt;

&lt;p&gt;Rotations only rearrange a few pointers, so each one is &lt;strong&gt;O(1)&lt;/strong&gt;. That's why AVL insert, delete and search all stay &lt;strong&gt;O(log n)&lt;/strong&gt; in the worst case.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two basic moves
&lt;/h2&gt;

&lt;p&gt;Every AVL fix is built from two moves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right rotation&lt;/strong&gt; (used when the tree leans left):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      z                y
     /               /   \
    y        →      x     z
   /
  x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Left rotation&lt;/strong&gt; (used when the tree leans right):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  z                    y
   \                 /   \
    y        →      z     x
     \
      x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both cases, the middle value &lt;code&gt;y&lt;/code&gt; moves up and becomes the new root of that subtree. The BST order (left &amp;lt; parent &amp;lt; right) is preserved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case 1: Left-Left (LL) → one right rotation
&lt;/h2&gt;

&lt;p&gt;Insert &lt;code&gt;30, 20, 10&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    30   (bf +2)  ← unbalanced
   /
  20     (bf +1)
 /
10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The node &lt;code&gt;30&lt;/code&gt; has balance factor &lt;strong&gt;+2&lt;/strong&gt; (leans left), and its left child &lt;code&gt;20&lt;/code&gt; also leans left (&lt;strong&gt;+1&lt;/strong&gt;). Both lean the same way, so &lt;strong&gt;one right rotation at 30&lt;/strong&gt; fixes it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    20
   /  \
  10   30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Case 2: Right-Right (RR) → one left rotation
&lt;/h2&gt;

&lt;p&gt;Insert &lt;code&gt;10, 20, 30&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dot"&gt;&lt;code&gt;&lt;span class="mi"&gt;10&lt;/span&gt;       &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;bf&lt;/span&gt; &lt;span class="err"&gt;−&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="nv"&gt;unbalanced&lt;/span&gt;
  &lt;span class="err"&gt;\&lt;/span&gt;
   &lt;span class="mi"&gt;20&lt;/span&gt;    &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;bf&lt;/span&gt; &lt;span class="err"&gt;−&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
     &lt;span class="err"&gt;\&lt;/span&gt;
      &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mirror image of Case 1. &lt;code&gt;10&lt;/code&gt; leans right (&lt;strong&gt;−2&lt;/strong&gt;) and its right child leans right too (&lt;strong&gt;−1&lt;/strong&gt;). &lt;strong&gt;One left rotation at 10&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    20
   /  \
  10   30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Case 3: Left-Right (LR) → left rotation, then right rotation
&lt;/h2&gt;

&lt;p&gt;Insert &lt;code&gt;30, 10, 20&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    30   (bf +2)  ← unbalanced
   /
  10     (bf −1)
    \
     20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's where people get stuck. &lt;code&gt;30&lt;/code&gt; leans &lt;strong&gt;left&lt;/strong&gt;, but its left child &lt;code&gt;10&lt;/code&gt; leans &lt;strong&gt;right&lt;/strong&gt;. The signs disagree, so a single right rotation at &lt;code&gt;30&lt;/code&gt; would just produce another unbalanced tree.&lt;/p&gt;

&lt;p&gt;The fix is two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Left rotation at 10&lt;/strong&gt; turns it into a Left-Left case:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      30
     /
    20
   /
  10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Right rotation at 30&lt;/strong&gt; finishes the job:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    20
   /  \
  10   30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Case 4: Right-Left (RL) → right rotation, then left rotation
&lt;/h2&gt;

&lt;p&gt;Insert &lt;code&gt;10, 30, 20&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight brainfuck"&gt;&lt;code&gt;&lt;span class="c1"&gt;10       (bf −2)  ← unbalanced
  \
   30    (bf &lt;/span&gt;&lt;span class="nf"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;1)
  /
 20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mirror of Case 3. &lt;code&gt;10&lt;/code&gt; leans right but its right child leans left. &lt;strong&gt;Right rotation at 30&lt;/strong&gt;, then &lt;strong&gt;left rotation at 10&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    20
   /  \
  10   30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The cheat sheet
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Unbalanced node&lt;/th&gt;
&lt;th&gt;Child leans&lt;/th&gt;
&lt;th&gt;Case&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;+2 (left heavy)&lt;/td&gt;
&lt;td&gt;left (+1 or 0)&lt;/td&gt;
&lt;td&gt;LL&lt;/td&gt;
&lt;td&gt;Right rotation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;−2 (right heavy)&lt;/td&gt;
&lt;td&gt;right (−1 or 0)&lt;/td&gt;
&lt;td&gt;RR&lt;/td&gt;
&lt;td&gt;Left rotation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+2 (left heavy)&lt;/td&gt;
&lt;td&gt;right (−1)&lt;/td&gt;
&lt;td&gt;LR&lt;/td&gt;
&lt;td&gt;Left rotate child, then right rotate node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;−2 (right heavy)&lt;/td&gt;
&lt;td&gt;left (+1)&lt;/td&gt;
&lt;td&gt;RL&lt;/td&gt;
&lt;td&gt;Right rotate child, then left rotate node&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Shortcut:&lt;/strong&gt; if the node and its child lean the &lt;strong&gt;same way&lt;/strong&gt;, one rotation. If they lean &lt;strong&gt;opposite ways&lt;/strong&gt;, two rotations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The code
&lt;/h2&gt;

&lt;p&gt;Here's the core of it in Python. Each node stores its height so balance factors are cheap to compute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rotate_right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;
    &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rotate_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;
    &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="c1"&gt;# LL
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;rotate_right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="c1"&gt;# RR
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;rotate_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="c1"&gt;# LR
&lt;/span&gt;        &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rotate_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;rotate_right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="c1"&gt;# RL
&lt;/span&gt;        &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rotate_right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;rotate_left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;rotate_right&lt;/code&gt; and &lt;code&gt;rotate_left&lt;/code&gt; each change just two pointers and update two heights. That's the whole O(1) trick.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch it happen instead of drawing it
&lt;/h2&gt;

&lt;p&gt;Static diagrams only get you so far. The moment it really clicks is when you watch the balance factors change after each insert and see the subtree swing into place.&lt;/p&gt;

&lt;p&gt;I built a free visualizer for exactly this: &lt;strong&gt;&lt;a href="https://vizstep.com/workspace/avl-tree" rel="noopener noreferrer"&gt;AVL tree visualization on VizStep&lt;/a&gt;&lt;/strong&gt;. Insert your own values and step forward or back through each operation. It calls out the balance factor that triggered a rebalance ("Balance factor at 30 is 2"), names the rotation case (LL, RR, LR or RL), and highlights the matching pseudocode line. It's free, with no sign-up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw7l791dlvddmtn46iozs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw7l791dlvddmtn46iozs.png" alt="Inserting 30, 20, 10 in VizStep's AVL tree visualizer triggers an LL rotation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try these sequences to trigger each case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;30, 20, 10&lt;/code&gt; → LL&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;10, 20, 30&lt;/code&gt; → RR&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;30, 10, 20&lt;/code&gt; → LR&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;10, 30, 20&lt;/code&gt; → RL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to see why AVL trees are worth the extra work, compare it with a plain BST on the same input: &lt;strong&gt;&lt;a href="https://vizstep.com/compare/binary-search-tree-vs-avl-tree" rel="noopener noreferrer"&gt;BST vs AVL Tree&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An AVL tree keeps every balance factor in &lt;strong&gt;{−1, 0, +1}&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same-direction lean&lt;/strong&gt; (LL, RR) needs &lt;strong&gt;one&lt;/strong&gt; rotation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opposite-direction lean&lt;/strong&gt; (LR, RL) needs &lt;strong&gt;two&lt;/strong&gt; rotations, and the first one just converts it into the simple case.&lt;/li&gt;
&lt;li&gt;Each rotation is &lt;strong&gt;O(1)&lt;/strong&gt;, so insert, delete and search stay &lt;strong&gt;O(log n)&lt;/strong&gt; in the worst case.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this helped, drop a comment with the data structure you'd like broken down next. Red-black trees and heaps are on my list.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>datastructures</category>
      <category>computerscience</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
