    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Pointer Reversal: An Algorithm Design Technique</title>
        <link>https://members.accu.org/index.php/articles/836</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 17, #5 - Oct 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c94/">175</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-94/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+94/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Pointer Reversal: An Algorithm Design Technique</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 October 2005 06:00:00 +01:00 or Sun, 02 October 2005 06:00:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>To summarize, as memory goes too low, garbage collection could kick in, but it in turn needs memory to maintain a traversal stack â€¦ Quite a catch-22.</p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a>Why Do We Need
Yet Another Algorithm Technique?</h2>
</div>
<p>I came across the Schorr and Waite algorithm while studying
garbage collection in Knuth. (See algorithm E, section 2.3.5 of
Knuth Volume I.) One phase in garbage collection typically consists
of marking nodes of a data structure not in use. These data
structures are Lists. Knuth defines Lists as &quot;a finite sequence of
zero or more atoms or Lists&quot;. Any forest is a List. Unlike forests,
Lists can have cycles. And just the way forests are represented as
binary trees, two links are used, each link with a different
meaning.</p>
<p>There are three types of Nodes:</p>
<div class="orderedlist">
<ol type="i">
<li>
<p>List Heads</p>
</li>
<li>
<p>Atom Nodes</p>
</li>
<li>
<p>List Nodes</p>
</li>
</ol>
</div>
<p>An <tt class="literal">ATOM</tt> field is maintained, which is
<tt class="literal">true</tt> for Atom nodes and <tt class=
"literal">false</tt> for List nodes. For a List node, two links,
<tt class="literal">DLINK</tt> and <tt class="literal">RLINK</tt>
are maintained. If <tt class="literal">ATOM</tt> is false and
<tt class="literal">DLINK</tt> is non-null, it points to a List
Head. If <tt class="literal">ATOM</tt> is true, <tt class=
"literal">DLINK</tt> is irrelevant.</p>
<p>Given a collection of List Heads, you need to visits all nodes
reachable from each List Head and mark them. You need to keep track
of where you came from and so need to maintain a stack. But there
might not be enough memory to keep the stack!!!</p>
<p>To summarize, as memory goes too low, garbage collection could
kick in, but it in turn needs memory to maintain a traversal stack
&hellip; Quite a catch-22.</p>
<p>The Schorr and Waite is an elegant algorithm that solves this
problem. It alters the pointer fields of the data structure itself
to maintain the traversal stack ( Pointer Reuse &#9786; ). Suppose
Node A points to Node B and B points to Node C. When the algorithm
is executing and marking Node C, it temporarily alters the pointers
so that C points to B and B points to A. Hence the name Pointer
Reversal. When the algorithm pops the stack, it restores ( reverses
back ) the pointers to their original values.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e72" id="d0e72"></a>The ATOM
Trick</h2>
</div>
<p>List Nodes have an <tt class="literal">ATOM</tt> bit which is
used skip <tt class="literal">ATOM</tt> nodes, after they are
marked. For a List Node, this bit is always false. The algorithm
uses this bit again ( in a context where it is known to be false )
for remembering state for Linked Nodes!! As pseudo-code</p>
<pre class="programlisting">
if ( ATOM = true )
{
 mark this node and skip rest of the processing
}
else
{
  if ( we changed DLINK as a stack link )
    ATOM = true
  .....
/*Now here, when we want to reverse the link*/
  if(  ATOM = true )
  { 
    we came over a DLINK ( and hence changed it ) 
  }
  else
  {
    we came over a RLINK (and hence changed it)
  }
}
</pre>
<p>The clever trick is manipulation of the <tt class=
"literal">ATOM</tt> bit. While processing a List Node <tt class=
"literal">ATOM</tt> is <tt class="literal">false</tt>, so we set
<tt class="literal">ATOM = true</tt> to remember one pointer and
<tt class="literal">ATOM = false</tt> ( the default ) to remember
other.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e102" id="d0e102"></a>Application
to Binary Trees (And The Good Old Inorder Traversal)</h2>
</div>
<p>However, as it turns out, we don't need this <tt class=
"literal">ATOM</tt> bit for binary trees&hellip; We exploit the
properties of binary trees (no cycles, all nodes are List nodes
etc.) and use the traversal property ( inorder traversal ) in place
of the <tt class="literal">ATOM</tt> bit.</p>
<p>The algorithm, in Knuthspeak, looks as below: ( See notation
below )</p>
<pre class="programlisting">
K1. Set P &lt;- Root, T &lt;- ^. [ Root is root of binary tree, ^ stands for null pointer ].

K2. If  LLINK( P ) = ^ goto K3. Otherwise, set R &lt;- LLINK(P), 
  LLINK(P) &lt;- T, T &lt;- P [ pointer reversed ], P &lt;- R and repeat this step.

K3. Set MARK(P) &lt;- 1. If RLINK(P) = ^ goto K4. Otherwise, set R &lt;- RLINK(P), 
  RLINK(P) &lt;- T, T &lt;- P, P &lt;- R. Goto K2.

K4. If T = ^, the algorithm terminates. Otherwise, if MARK(T) = 0, Q &lt;- LLINK(T), 
  LLINK(T) = P, P &lt;- T, T &lt;- Q and goto K3. Else, [parent is marked ], 
  set Q &lt;- RLINK(T), RLINK(T) &lt;- P, P &lt;- T, T &lt;- Q and repeat this step. 

Notation: 1. = is equality operator (= =)
                2. T &lt;- P is assignment - T is assigned the value of P
                3. LLINK(P) is really P-&gt;LLINK in C/C++

Step K2 reverses left pointer.
K3 reverses the right pointer.
K4 pops back ( i.e. restores pointers )
</pre>
<p>Note that we are essentially traversing (marking nodes in) the
tree in in-order traversal. It is essentially an in-order traversal
without any explicit stack. Instead we need a <tt class=
"literal">MARK</tt> bit ( but note that the <tt class=
"literal">MARK</tt> bit really need not be explicitly maintained -
you can use other contextual info ).</p>
<p>Note that, in K3, when a node is marked, its left subtree ( if
any ) is all marked.</p>
<p>I tried the algorithm with boundary test cases (a binary tree
with just the root node, a degenerate tree with only left or only
right nodes etc&hellip;). It works correctly&hellip;</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e129" id="d0e129"></a>The Master
Verifies&hellip;</h2>
</div>
<p>This appears as an exercise in Knuth (2.3.5 - exercise 7). When
I come up with a solution, verifying it always teaches me something
more&hellip; This was a rare case where Don's agreed with
mine&hellip; Sometime back, I solved exercise 10 and when tallied
with the book solution, I came across a very novel use of
queues.</p>
<p>Over the years, as I keep reading Knuth I have grown a deep
respect and adoration for these volumes. The text is crisp, sharp
and cracking the exercises make you ecstatic. Nirvana, anyone?</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
