00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028 #include "et-forest.h"
00029
00030 struct et_forest_occurrence;
00031 typedef struct et_forest_occurrence* et_forest_occurrence_t;
00032
00033
00034 struct et_forest
00035 {
00036
00037 int nnodes;
00038 };
00039
00040
00041
00042
00043 struct et_forest_occurrence
00044 {
00045
00046 et_forest_occurrence_t parent;
00047
00048
00049 et_forest_occurrence_t left, right;
00050
00051
00052 int count_left, count_right;
00053
00054
00055 et_forest_occurrence_t next;
00056
00057
00058 et_forest_node_t node;
00059 };
00060
00061
00062
00063 struct et_forest_node
00064 {
00065 et_forest_t forest;
00066 void *value;
00067
00068
00069 et_forest_occurrence_t first, last;
00070 };
00071
00072
00073 static et_forest_occurrence_t splay PARAMS ((et_forest_occurrence_t));
00074 static void remove_all_occurrences PARAMS ((et_forest_node_t));
00075 static inline et_forest_occurrence_t find_leftmost_node
00076 PARAMS ((et_forest_occurrence_t));
00077 static inline et_forest_occurrence_t find_rightmost_node
00078 PARAMS ((et_forest_occurrence_t));
00079 static int calculate_value PARAMS ((et_forest_occurrence_t));
00080
00081
00082 static inline et_forest_occurrence_t
00083 find_leftmost_node (occ)
00084 et_forest_occurrence_t occ;
00085 {
00086 while (occ->left)
00087 occ = occ->left;
00088
00089 return occ;
00090 }
00091
00092
00093 static inline et_forest_occurrence_t
00094 find_rightmost_node (occ)
00095 et_forest_occurrence_t occ;
00096 {
00097 while (occ->right)
00098 occ = occ->right;
00099 return occ;
00100 }
00101
00102
00103
00104 static et_forest_occurrence_t
00105 splay (node)
00106 et_forest_occurrence_t node;
00107 {
00108 et_forest_occurrence_t parent;
00109 et_forest_occurrence_t grandparent;
00110
00111 while (1)
00112 {
00113 parent = node->parent;
00114
00115 if (! parent)
00116 return node;
00117
00118 grandparent = parent->parent;
00119
00120 if (! grandparent)
00121 break;
00122
00123
00124
00125 if (node == parent->left)
00126 {
00127 if (parent == grandparent->left)
00128 {
00129 et_forest_occurrence_t node1, node2;
00130 int count1, count2;
00131
00132 node1 = node->right;
00133 count1 = node->count_right;
00134 node2 = parent->right;
00135 count2 = parent->count_right;
00136
00137 grandparent->left = node2;
00138 grandparent->count_left = count2;
00139 if (node2)
00140 node2->parent = grandparent;
00141 parent->left = node1;
00142 parent->count_left = count1;
00143 if (node1)
00144 node1->parent = parent;
00145 parent->right = grandparent;
00146 parent->count_right = count2 + grandparent->count_right + 1;
00147 node->right = parent;
00148 node->count_right = count1 + parent->count_right + 1;
00149
00150 node->parent = grandparent->parent;
00151 parent->parent = node;
00152 grandparent->parent = parent;
00153
00154 if (node->parent)
00155 {
00156 if (node->parent->left == grandparent)
00157 node->parent->left = node;
00158 else
00159 node->parent->right = node;
00160 }
00161 }
00162 else
00163 {
00164
00165 et_forest_occurrence_t node1, node2;
00166 int count1, count2;
00167
00168 node1 = node->left;
00169 count1 = node->count_left;
00170 node2 = node->right;
00171 count2 = node->count_right;
00172
00173 grandparent->right = node1;
00174 grandparent->count_right = count1;
00175 if (node1)
00176 node1->parent = grandparent;
00177 parent->left = node2;
00178 parent->count_left = count2;
00179 if (node2)
00180 node2->parent = parent;
00181 node->left = grandparent;
00182 node->count_left = grandparent->count_left + count1 + 1;
00183 node->right = parent;
00184 node->count_right = parent->count_right + count2 + 1;
00185
00186 node->parent = grandparent->parent;
00187 parent->parent = node;
00188 grandparent->parent = node;
00189
00190 if (node->parent)
00191 {
00192 if (node->parent->left == grandparent)
00193 node->parent->left = node;
00194 else
00195 node->parent->right = node;
00196 }
00197 }
00198 }
00199 else
00200 {
00201
00202 if (parent == grandparent->left)
00203 {
00204 et_forest_occurrence_t node1, node2;
00205 int count1, count2;
00206
00207 node1 = node->left;
00208 count1 = node->count_left;
00209 node2 = node->right;
00210 count2 = node->count_right;
00211
00212 parent->right = node1;
00213 parent->count_right = count1;
00214 if (node1)
00215 node1->parent = parent;
00216 grandparent->left = node2;
00217 grandparent->count_left = count2;
00218 if (node2)
00219 node2->parent = grandparent;
00220 node->left = parent;
00221 node->count_left = parent->count_left + count1 + 1;
00222 node->right = grandparent;
00223 node->count_right = grandparent->count_right + count2 + 1;
00224
00225 node->parent = grandparent->parent;
00226 parent->parent = node;
00227 grandparent->parent = node;
00228
00229 if (node->parent)
00230 {
00231 if (node->parent->left == grandparent)
00232 node->parent->left = node;
00233 else
00234 node->parent->right = node;
00235 }
00236 }
00237 else
00238 {
00239
00240 et_forest_occurrence_t node1, node2;
00241 int count1, count2;
00242
00243 node1 = node->left;
00244 count1 = node->count_left;
00245 node2 = parent->left;
00246 count2 = parent->count_left;
00247
00248 grandparent->right = node2;
00249 grandparent->count_right = count2;
00250 if (node2)
00251 node2->parent = grandparent;
00252 parent->right = node1;
00253 parent->count_right = count1;
00254 if (node1)
00255 node1->parent = parent;
00256 parent->left = grandparent;
00257 parent->count_left = count2 + grandparent->count_left + 1;
00258 node->left = parent;
00259 node->count_left = count1 + parent->count_left + 1;
00260
00261 node->parent = grandparent->parent;
00262 parent->parent = node;
00263 grandparent->parent = parent;
00264
00265 if (node->parent)
00266 {
00267 if (node->parent->left == grandparent)
00268 node->parent->left = node;
00269 else
00270 node->parent->right = node;
00271 }
00272 }
00273 }
00274
00275 }
00276
00277
00278
00279
00280 if (node == parent->left)
00281 {
00282 et_forest_occurrence_t node1;
00283 int count1;
00284
00285 node1 = node->right;
00286 count1 = node->count_right;
00287
00288 parent->left = node1;
00289 parent->count_left = count1;
00290 if (node1)
00291 node1->parent = parent;
00292 node->right = parent;
00293 node->count_right = parent->count_right + 1 + count1;
00294 node->parent = parent->parent;
00295 parent->parent = node;
00296
00297 if (node->parent)
00298 {
00299 if (node->parent->left == parent)
00300 node->parent->left = node;
00301 else
00302 node->parent->right = node;
00303 }
00304 }
00305 else
00306 {
00307
00308 et_forest_occurrence_t node1;
00309 int count1;
00310
00311 node1 = node->left;
00312 count1 = node->count_left;
00313
00314 parent->right = node1;
00315 parent->count_right = count1;
00316 if (node1)
00317 node1->parent = parent;
00318 node->left = parent;
00319 node->count_left = parent->count_left + 1 + count1;
00320 node->parent = parent->parent;
00321 parent->parent = node;
00322
00323 if (node->parent)
00324 {
00325 if (node->parent->left == parent)
00326 node->parent->left = node;
00327 else
00328 node->parent->right = node;
00329 }
00330 }
00331
00332 return node;
00333 }
00334
00335
00336 static void
00337 remove_all_occurrences (forest_node)
00338 et_forest_node_t forest_node;
00339 {
00340 et_forest_occurrence_t first = forest_node->first;
00341 et_forest_occurrence_t last = forest_node->last;
00342 et_forest_occurrence_t node;
00343
00344 splay (first);
00345
00346 if (first->left)
00347 first->left->parent = 0;
00348 if (first->right)
00349 first->right->parent = 0;
00350
00351 if (last != first)
00352 {
00353 splay (last);
00354
00355 if (last->left)
00356 last->left->parent = 0;
00357 if (last->right)
00358 last->right->parent = 0;
00359 }
00360
00361 if (last->right && first->left)
00362 {
00363
00364 et_forest_occurrence_t prev_node, next_node;
00365
00366 prev_node = splay (find_rightmost_node (first->left));
00367 next_node = splay (find_leftmost_node (last->right));
00368
00369
00370 if (prev_node->next != next_node)
00371 abort ();
00372
00373 prev_node->right = next_node->right;
00374 prev_node->count_right = next_node->count_right;
00375 prev_node->next = next_node->next;
00376 if (prev_node->right)
00377 prev_node->right->parent = prev_node;
00378
00379 if (prev_node->node->last == next_node)
00380 prev_node->node->last = prev_node;
00381
00382 free (next_node);
00383 }
00384
00385 if (first != last)
00386 {
00387 node = first->next;
00388
00389 while (node != last)
00390 {
00391 et_forest_occurrence_t next_node;
00392
00393 splay (node);
00394
00395 if (node->left)
00396 node->left->parent = 0;
00397 if (node->right)
00398 node->right->parent = 0;
00399
00400 next_node = node->next;
00401 free (node);
00402 node = next_node;
00403 }
00404 }
00405
00406 free (first);
00407 if (first != last)
00408 free (last);
00409 }
00410
00411
00412 static inline int
00413 calculate_value (node)
00414 et_forest_occurrence_t node;
00415 {
00416 int value = node->count_left;
00417
00418 while (node->parent)
00419 {
00420 if (node == node->parent->right)
00421 value += node->parent->count_left + 1;
00422
00423 node = node->parent;
00424 }
00425
00426 return value;
00427 }
00428
00429
00430
00431
00432
00433 et_forest_t
00434 et_forest_create ()
00435 {
00436
00437 et_forest_t forest = xmalloc (sizeof (struct et_forest));
00438
00439 forest->nnodes = 0;
00440 return forest;
00441 }
00442
00443
00444
00445
00446 void
00447 et_forest_delete (forest)
00448 et_forest_t forest;
00449 {
00450 if (forest->nnodes)
00451 abort ();
00452
00453 free (forest);
00454 }
00455
00456
00457
00458 et_forest_node_t
00459 et_forest_add_node (forest, value)
00460 et_forest_t forest;
00461 void *value;
00462 {
00463
00464 et_forest_node_t node;
00465 et_forest_occurrence_t occ;
00466
00467 node = xmalloc (sizeof (struct et_forest_node));
00468 occ = xmalloc (sizeof (struct et_forest_occurrence));
00469
00470 node->first = node->last = occ;
00471 node->value = value;
00472 forest->nnodes++;
00473
00474 occ->node = node;
00475 occ->left = occ->right = occ->parent = 0;
00476 occ->next = 0;
00477 occ->count_left = occ->count_right = 0;
00478 return node;
00479 }
00480
00481
00482
00483 int
00484 et_forest_add_edge (forest, parent_node, child_node)
00485 et_forest_t forest ATTRIBUTE_UNUSED;
00486 et_forest_node_t parent_node;
00487 et_forest_node_t child_node;
00488 {
00489 et_forest_occurrence_t new_occ, parent_occ, child_occ;
00490
00491 if (! parent_node || ! child_node)
00492 abort ();
00493
00494 parent_occ = parent_node->first;
00495 child_occ = child_node->first;
00496
00497 splay (parent_occ);
00498 splay (child_occ);
00499
00500 if (parent_occ->parent)
00501 return 0;
00502
00503 if (child_occ->left)
00504 abort ();
00505
00506 new_occ = xmalloc (sizeof (struct et_forest_occurrence));
00507
00508 new_occ->node = parent_node;
00509 new_occ->left = child_occ;
00510 new_occ->count_left = child_occ->count_right + 1;
00511 new_occ->right = parent_occ->right;
00512 new_occ->count_right = parent_occ->count_right;
00513 new_occ->parent = parent_occ;
00514 new_occ->next = parent_occ->next;
00515 child_occ->parent = new_occ;
00516 parent_occ->right = new_occ;
00517 parent_occ->count_right = new_occ->count_left + new_occ->count_right + 1;
00518 parent_occ->next = new_occ;
00519 if (new_occ->right)
00520 new_occ->right->parent = new_occ;
00521
00522 if (parent_node->last == parent_occ)
00523 parent_node->last = new_occ;
00524 return 1;
00525 }
00526
00527
00528 void
00529 et_forest_remove_node (forest, node)
00530 et_forest_t forest;
00531 et_forest_node_t node;
00532 {
00533 remove_all_occurrences (node);
00534 forest->nnodes--;
00535
00536 free (node);
00537 }
00538
00539
00540
00541 int
00542 et_forest_remove_edge (forest, parent_node, child_node)
00543 et_forest_t forest ATTRIBUTE_UNUSED;
00544 et_forest_node_t parent_node;
00545 et_forest_node_t child_node;
00546 {
00547 et_forest_occurrence_t parent_pre_occ, parent_post_occ;
00548
00549 splay (child_node->first);
00550
00551 if (! child_node->first->left)
00552 return 0;
00553
00554 parent_pre_occ = find_rightmost_node (child_node->first->left);
00555 if (parent_pre_occ->node != parent_node)
00556 abort ();
00557
00558 splay (parent_pre_occ);
00559 parent_pre_occ->right->parent = 0;
00560
00561 parent_post_occ = parent_pre_occ->next;
00562 splay (parent_post_occ);
00563
00564 parent_post_occ->left->parent = 0;
00565
00566 parent_pre_occ->right = parent_post_occ->right;
00567 parent_pre_occ->count_right = parent_post_occ->count_right;
00568 if (parent_post_occ->right)
00569 parent_post_occ->right->parent = parent_pre_occ;
00570
00571 parent_pre_occ->next = parent_post_occ->next;
00572
00573 if (parent_post_occ == parent_node->last)
00574 parent_node->last = parent_pre_occ;
00575
00576 free (parent_post_occ);
00577 return 1;
00578 }
00579
00580
00581 et_forest_node_t
00582 et_forest_parent (forest, node)
00583 et_forest_t forest ATTRIBUTE_UNUSED;
00584 et_forest_node_t node;
00585 {
00586 splay (node->first);
00587
00588 if (node->first->left)
00589 return find_rightmost_node (node->first->left)->node;
00590 else
00591 return 0;
00592 }
00593
00594
00595
00596
00597 et_forest_node_t
00598 et_forest_common_ancestor (forest, node1, node2)
00599 et_forest_t forest ATTRIBUTE_UNUSED;
00600 et_forest_node_t node1;
00601 et_forest_node_t node2;
00602 {
00603 int value1, value2, max_value;
00604 et_forest_node_t ancestor;
00605
00606 if (node1 == node2)
00607 return node1;
00608
00609 if (! node1 || ! node2)
00610 abort ();
00611
00612 splay (node1->first);
00613 splay (node2->first);
00614
00615 if (! node1->first->parent)
00616 return 0;
00617
00618 value2 = calculate_value (node2->first);
00619 value1 = calculate_value (node1->first);
00620
00621 if (value1 < value2)
00622 {
00623 ancestor = node1;
00624 max_value = value2;
00625 }
00626 else
00627 {
00628 ancestor = node2;
00629 max_value = value1;
00630 }
00631
00632 while (calculate_value (ancestor->last) < max_value)
00633 {
00634
00635 splay (ancestor->first);
00636 ancestor = find_rightmost_node (ancestor->first->left) ->node;
00637 }
00638
00639 return ancestor;
00640 }
00641
00642
00643 void *
00644 et_forest_node_value (forest, node)
00645 et_forest_t forest ATTRIBUTE_UNUSED;
00646 et_forest_node_t node;
00647 {
00648
00649 if (!node)
00650 return NULL;
00651 return node->value;
00652 }
00653
00654
00655
00656 int
00657 et_forest_enumerate_sons (forest, node, array)
00658 et_forest_t forest ATTRIBUTE_UNUSED;
00659 et_forest_node_t node;
00660 et_forest_node_t *array;
00661 {
00662 int n = 0;
00663 et_forest_occurrence_t occ = node->first, stop = node->last, occ1;
00664
00665
00666
00667
00668 while (occ != stop)
00669 {
00670 splay (occ);
00671 if (occ->right)
00672 {
00673 occ1 = find_leftmost_node (occ->right);
00674 if (occ1->node->first == occ1)
00675 array[n++] = occ1->node;
00676 }
00677 occ = occ->next;
00678 }
00679 return n;
00680 }