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

MultiPlatform

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