_p_heap.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:11k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _p_heap.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/impl/p_heap.h>
  12. static p_heap const *class_ptr;
  13. // ============== comparison_link Macros (s.n.) ================================
  14. #define comparison_link(with_el,new_el)
  15.   if (cmp(with_el->key,new_el->key)<0)
  16.     { with_el->r_child=new_el->r_child;
  17.       if (with_el->r_child!=nil)
  18.               with_el->r_child->parent=with_el;
  19.       new_el->r_child=with_el->l_child;
  20.       if (new_el->r_child!=nil)
  21.               new_el->r_child->parent=new_el;
  22.       new_el->parent=with_el;  
  23.       with_el->l_child=new_el; }
  24.   else
  25.     { with_el->r_child=new_el->l_child;
  26.       if (with_el->r_child!=nil)
  27.               with_el->r_child->parent=with_el;
  28.       new_el->parent=with_el->parent;
  29.       if (new_el->parent!=nil)
  30.               new_el->parent->r_child=new_el; 
  31.       new_el->l_child=with_el;
  32.       with_el->parent=new_el;
  33.       with_el = new_el; }
  34. #define int_comparison_link(with_el,new_el)
  35.   if (with_el->key < new_el->key)
  36.     { with_el->r_child=new_el->r_child;
  37.       if (with_el->r_child!=nil)
  38.               with_el->r_child->parent=with_el;
  39.       new_el->r_child=with_el->l_child;
  40.       if (new_el->r_child!=nil)
  41.               new_el->r_child->parent=new_el;
  42.       new_el->parent=with_el;  
  43.       with_el->l_child=new_el; }
  44.   else
  45.     { with_el->r_child=new_el->l_child;
  46.       if (with_el->r_child!=nil)
  47.               with_el->r_child->parent=with_el;
  48.       new_el->parent=with_el->parent;
  49.       if (new_el->parent!=nil)
  50.               new_el->parent->r_child=new_el; 
  51.       new_el->l_child=with_el;
  52.       with_el->parent=new_el;
  53.       with_el = new_el; }
  54. //====== construct (p_heap&) ===========================================
  55. p_heap::p_heap(const p_heap& with)
  56. {
  57.     item_count =0;
  58.     if((this!=&with)&&(with.item_count>0)){
  59.         class_ptr=&with;
  60.         copy_sub_tree(head,with.head);
  61.         class_ptr=this;
  62.     }
  63. }
  64. //====== operator = =====================================================
  65. p_heap& p_heap::operator=(const p_heap& with)
  66. {
  67.       if(this!=&with){
  68.          if((with.item_count>0)&&(item_count>0))
  69.                 clear();
  70.         class_ptr=&with;
  71.         copy_sub_tree(head,with.head);
  72.         class_ptr=this;
  73.                 
  74.         }
  75.         return(*this);
  76. }
  77. //=========== copy_sub_tree =============================================
  78. void  p_heap::copy_sub_tree(ph_item* whereto,ph_item* from) 
  79. {
  80.    if (item_count==0)   // target tree is empty 
  81.    {
  82.         
  83.          head =new ph_item(from->key,from->inf);
  84.          class_ptr->copy_key(head->key);
  85.          class_ptr->copy_inf(head->inf);
  86.          item_count++;
  87.         
  88.          do_copy(head,from->l_child,true);
  89.    }
  90.  
  91.    else
  92.         
  93.                 if ((cmp(whereto->key,from->key)<=0)  // precondition:
  94.                         &&(whereto->l_child==nil))    // subelement <= parent
  95.                 
  96.                         do_copy(whereto,from,true);
  97.                         // true: that is left child from whereto        
  98. }
  99.  
  100. //====== do_copy ======================================================
  101. void p_heap::do_copy(ph_item* father,ph_item* from,bool direction)
  102. {
  103. // direction : false=right true=left
  104.         
  105.         ph_item* hilf=new_ph_item(from->key,from->inf);
  106.         
  107.         hilf->parent=father;
  108.         if (direction)
  109.                 father->l_child=hilf;
  110.         else
  111.                 father->r_child=hilf;
  112.         if (from->l_child!=nil)
  113.                 do_copy(hilf,from->l_child,true);
  114.                 
  115.         if (from->r_child!=nil)
  116.                 do_copy(hilf,from->r_child,false);
  117. }
  118. //===== new_ph_item =====================================================
  119. ph_item* p_heap::new_ph_item(GenPtr key,GenPtr inf)
  120. {
  121.         ph_item* help=new ph_item(key,inf);
  122.         copy_key(help->key);
  123.         copy_inf(help->inf);
  124.         help->parent=nil;
  125.         item_count++;
  126.         return help;
  127. }
  128.         
  129.                 
  130. // ========== clear ====================================================
  131. void p_heap::clear()
  132. {
  133.   if (item_count>0)
  134.         clear_sub_tree(head);
  135.         
  136. }
  137. // ======= clear_sub_tree ===============================================
  138. void p_heap::clear_sub_tree(ph_item* sub)
  139. {
  140.         
  141.         if (sub->l_child!=nil)
  142.                 clear_sub_tree(sub->l_child);
  143.         if (sub->r_child!=nil)
  144.                 clear_sub_tree(sub->r_child);
  145.         if (sub->parent!=nil)
  146.                 if(sub->parent->l_child==sub)
  147.                         sub->parent->l_child=nil;
  148.                 else
  149.                         sub->parent->r_child=nil;
  150.         clear_key(sub->key);
  151.         clear_inf(sub->inf);
  152.         delete(sub);
  153.         item_count--;
  154. }
  155.                 
  156. //======= insert =======================================================
  157. ph_item* p_heap::insert(GenPtr key,GenPtr inf)
  158. {       
  159.         ph_item* help;
  160.         help = new ph_item(key,inf);
  161.         copy_key(help->key);
  162.         copy_inf(help->inf);
  163.         if (item_count==0)      // very first element
  164.           { item_count++;
  165.             head=help;
  166.             return help;
  167.            }
  168.         else                    // just another element
  169.           { item_count++;
  170.             comparison_link(head,help);
  171.             return help;
  172.            }
  173.         
  174. }
  175. // ====== decrease_key ==================================================
  176. void p_heap::decrease_key(ph_item* which,GenPtr key)
  177. {
  178.    register ph_item* help2=nil;
  179.    register ph_item* which_parent = which->parent;
  180.    if (int_type())
  181.      if (key <= which->key)  // smaller or equal to the old element
  182.       { 
  183.         which->key=key;
  184.    
  185.         if (which!=head)         // which is not already minimum
  186.         { if (which->r_child!=nil)
  187.           { help2=which->r_child;
  188.             help2->parent=which_parent;
  189.             which->r_child=nil;
  190.            }
  191.    
  192.           if (which_parent->l_child==which)
  193.              which_parent->l_child=help2;
  194.           else                    
  195.              which_parent->r_child=help2;
  196.    
  197.           which->parent=nil;
  198.           int_comparison_link(head,which);
  199.          }
  200.       }
  201.      else /* error */;
  202.    else
  203.      if (cmp(key,which->key)<=0)  // smaller or equal to the old element
  204.       { 
  205.         clear_key(which->key);
  206.         which->key=key;
  207.         copy_key(which->key);
  208.    
  209.         if (which!=head)         // which is not already minimum
  210.         { if (which->r_child!=nil)
  211.           { help2=which->r_child;
  212.             help2->parent=which_parent;
  213.             which->r_child=nil;
  214.            }
  215.    
  216.           if (which_parent->l_child==which)
  217.              which_parent->l_child=help2;
  218.           else                    
  219.              which_parent->r_child=help2;
  220.    
  221.           which->parent=nil;
  222.           comparison_link(head,which);
  223.          }
  224.       }
  225.      else /* error */;
  226. }                       
  227.                 
  228. //========= delete_min_multipass ()  (multipass algorithm) =============
  229. void p_heap::delete_min_multipass()
  230. {
  231.  if (item_count==1)     // only one element in structure
  232.    {
  233.         clear_key(head->key);
  234.         clear_inf(head->inf);
  235.         delete head;
  236.         item_count=0;
  237.    }
  238.    else
  239.    {
  240.         head=head->l_child;
  241.         clear_key(head->parent->key);
  242.         clear_inf(head->parent->inf);
  243.         delete head->parent;    // delete min
  244.         head->parent=nil;
  245.         item_count--;
  246.         
  247.       if (head->r_child!=nil)   // there are two ore more consecutive elements
  248.         head=multipass(head);
  249.     
  250.   }// end else
  251. }
  252. //======== delete_min_twopass, (twopass algorithm) ============================
  253. void p_heap::delete_min_twopass()
  254. {
  255.         
  256.    if (item_count==1)   // only one element in structure
  257.    {
  258.         clear_key(head->key);
  259.         clear_inf(head->inf);
  260.         delete head;
  261.         item_count=0;
  262.    }
  263.    else
  264.    {
  265.         head=head->l_child;
  266.         clear_key(head->parent->key);
  267.         clear_inf(head->parent->inf);
  268.         delete head->parent;    // delete min
  269.         head->parent=nil;
  270.         item_count--;
  271.         
  272.       if (head->r_child!=nil)   // there are two ore more consecutive elements
  273.       
  274.         head=twopass(head);
  275.         
  276.       } // end else
  277. }
  278. // ============== twopass ================================================              
  279.         
  280. ph_item*  p_heap::twopass(ph_item* h)
  281. {
  282.  //pass 1 : left to right comparison link (successive pairs of root nodes)
  283.   register ph_item* help1,*help2;
  284.   help1=h;
  285.   help2=h->r_child;
  286.   
  287.   if (int_type())
  288.         while (help2!=nil)               // there are 2 ore more elements left
  289.         { h=help1->r_child->r_child;   // use of h as a helper
  290.           int_comparison_link(help1,help2);
  291.                 
  292.           if (h!=nil)       // first case comp _link
  293.              if (h->r_child!=nil)
  294.                { // second case
  295.                  // now we have to more nodes to test
  296.                  help2=h->r_child;
  297.                  help1=h;
  298.                 }
  299.              else
  300.                help2=nil;
  301.            else
  302.              { h=help1;     // last element in list
  303.                help2=nil;
  304.               }
  305.           }
  306.    else
  307.         while (help2!=nil)
  308.         { h=help1->r_child->r_child;
  309.           comparison_link(help1,help2);
  310.                 
  311.           if (h!=nil)
  312.              if (h->r_child!=nil)
  313.                { help2=h->r_child;
  314.                  help1=h;
  315.                 }
  316.              else
  317.                help2=nil;
  318.            else
  319.              { h=help1;
  320.                help2=nil;
  321.               }
  322.          }
  323.   //pass 2 : right to left comparison link (allways the two rightmost nodes)
  324.         help1=h->parent;
  325.         help2=h;
  326.    if (int_type())
  327.         while (help1!=nil)
  328.         { int_comparison_link(help1,help2);
  329.           h=help1;
  330.           help2=help1;
  331.           help1=help1->parent;
  332.          }
  333.     else
  334.         while (help1!=nil)
  335.         { comparison_link(help1,help2);
  336.           h=help1;
  337.           help2=help1;
  338.           help1=help1->parent;
  339.          }
  340.         
  341.  // h points now again to the very first element
  342.  return h;
  343. }
  344. // ================ multipass ==========================================
  345. ph_item* p_heap::multipass(ph_item* h)
  346. {
  347.           // now pass 1 (multi times) : left to right comparison link (successive pairs of root nodes)
  348.        ph_item* save=h;      
  349.        ph_item* help1,*help2;
  350.        while(h->r_child!=nil)
  351.        { save=h;
  352.          help1=h;
  353.          help2=h->r_child;
  354.         
  355.          while (help2!=nil)      // there are 2 ore more elements left
  356.          { save=help1->r_child->r_child; // use of save as a helper
  357.            comparison_link(help1,help2);
  358.                 
  359.            if (save!=nil)       // first case comp _link
  360.              if (save->r_child!=nil)
  361.                 { // second case
  362.                   // now we have to more nodes to test
  363.                   help2=save->r_child;
  364.                   help1=save;
  365.                  }
  366.               else
  367.                  help2=nil;
  368.            else
  369.               { save=help1;     // last element in list
  370.                 help2=nil;
  371.                }
  372.          } // end while (help2!=nil)
  373.         if (h->parent!=nil)      // may be first element is child (comp link)
  374.                 h=h->parent;
  375.     } // end while (repeat pass 1)
  376.   return h;
  377. }