diff options
| author | Toby Cubitt | 2011-05-27 19:58:29 -0300 |
|---|---|---|
| committer | Stefan Monnier | 2011-05-27 19:58:29 -0300 |
| commit | eb95d01d15ed25ed7e27ee4d1b883588c58ce306 (patch) | |
| tree | cbe322b2633ef81c26549854a60f6a04e66bc763 | |
| parent | 3769ddcf1eeb85bb3f408d90a8bb44f383620882 (diff) | |
| download | emacs-eb95d01d15ed25ed7e27ee4d1b883588c58ce306.tar.gz emacs-eb95d01d15ed25ed7e27ee4d1b883588c58ce306.zip | |
* lisp/emacs-lisp/avl-tree.el: New avl-tree-stack datatype. Add new
traversal functions for avl-trees.
(avl-tree--stack): New struct.
(avl-tree-stack-p, avl-tree--stack-repopulate): New funs.
(avl-tree-enter): Add optional `updatefun' arg.
(avl-tree--do-enter): Add optional `updatefun' arg. Change return value.
(avl-tree-delete): Add optional `test' and `nilflag' args.
(avl-tree--do-delete): Add `test' and `nilflag' args. Change return value.
(avl-tree-member): Add optional `nilflag'
(avl-tree-member-p): New function.
(avl-tree-mapc, avl-tree-mapf, avl-tree-mapcar): New functions.
(avl-tree-stack, avl-tree-stack-pop, avl-tree-stack-first)
(avl-tree-stack-empty-p): New functions.
| -rw-r--r-- | lisp/ChangeLog | 18 | ||||
| -rw-r--r-- | lisp/emacs-lisp/avl-tree.el | 304 |
2 files changed, 270 insertions, 52 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 2b6e0dc41f9..8c40eab356b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,21 @@ | |||
| 1 | 2009-11-23 Toby Cubitt <toby-predictive@dr-qubit.org> | 1 | 2009-11-23 Toby Cubitt <toby-predictive@dr-qubit.org> |
| 2 | 2 | ||
| 3 | * emacs-lisp/avl-tree.el: New avl-tree-stack datatype. Add new | ||
| 4 | traversal functions for avl-trees. | ||
| 5 | (avl-tree--stack): New struct. | ||
| 6 | (avl-tree-stack-p, avl-tree--stack-repopulate): New funs. | ||
| 7 | (avl-tree-enter): Add optional `updatefun' arg. | ||
| 8 | (avl-tree--do-enter): Add optional `updatefun' arg. Change return value. | ||
| 9 | (avl-tree-delete): Add optional `test' and `nilflag' args. | ||
| 10 | (avl-tree--do-delete): Add `test' and `nilflag' args. Change return value. | ||
| 11 | (avl-tree-member): Add optional `nilflag' | ||
| 12 | (avl-tree-member-p): New function. | ||
| 13 | (avl-tree-mapc, avl-tree-mapf, avl-tree-mapcar): New functions. | ||
| 14 | (avl-tree-stack, avl-tree-stack-pop, avl-tree-stack-first) | ||
| 15 | (avl-tree-stack-empty-p): New functions. | ||
| 16 | |||
| 17 | 2009-11-23 Toby Cubitt <toby-predictive@dr-qubit.org> | ||
| 18 | |||
| 3 | * emacs-lisp/avl-tree.el (avl-tree--del-balance): Rename from | 19 | * emacs-lisp/avl-tree.el (avl-tree--del-balance): Rename from |
| 4 | avl-tree--del-balance1 and make it work both ways. | 20 | avl-tree--del-balance1 and make it work both ways. |
| 5 | (avl-tree--del-balance2): Remove. | 21 | (avl-tree--del-balance2): Remove. |
| @@ -10,7 +26,7 @@ | |||
| 10 | New macros. | 26 | New macros. |
| 11 | (avl-tree--mapc, avl-tree-map): Add direction argument. | 27 | (avl-tree--mapc, avl-tree-map): Add direction argument. |
| 12 | 28 | ||
| 13 | 2011-05-27 David Michael <fedora.dm0@gmail.com> | 29 | 2011-05-27 David Michael <fedora.dm0@gmail.com> (tiny change) |
| 14 | 30 | ||
| 15 | * files.el (interpreter-mode-alist): Add rbash (bug#8745). | 31 | * files.el (interpreter-mode-alist): Add rbash (bug#8745). |
| 16 | 32 | ||
diff --git a/lisp/emacs-lisp/avl-tree.el b/lisp/emacs-lisp/avl-tree.el index 82585fd4322..e8b7a1f9a8b 100644 --- a/lisp/emacs-lisp/avl-tree.el +++ b/lisp/emacs-lisp/avl-tree.el | |||
| @@ -200,36 +200,52 @@ Return t if the height of the tree has shrunk." | |||
| 200 | (avl-tree--node-left br)) | 200 | (avl-tree--node-left br)) |
| 201 | t))) | 201 | t))) |
| 202 | 202 | ||
| 203 | (defun avl-tree--do-delete (cmpfun root branch data) | 203 | (defun avl-tree--do-delete (cmpfun root branch data test nilflag) |
| 204 | ;; Return t if the height of the tree has shrunk. | 204 | "Delete DATA from BRANCH of node ROOT. |
| 205 | \(See `avl-tree-delete' for TEST and NILFLAG). | ||
| 206 | |||
| 207 | Return cons cell (SHRUNK . DATA), where SHRUNK is t if the | ||
| 208 | height of the tree has shrunk and nil otherwise, and DATA is | ||
| 209 | the releted data." | ||
| 205 | (let ((br (avl-tree--node-branch root branch))) | 210 | (let ((br (avl-tree--node-branch root branch))) |
| 206 | (cond | 211 | (cond |
| 212 | ;; DATA not in tree. | ||
| 207 | ((null br) | 213 | ((null br) |
| 208 | nil) | 214 | (cons nil nilflag)) |
| 209 | 215 | ||
| 210 | ((funcall cmpfun data (avl-tree--node-data br)) | 216 | ((funcall cmpfun data (avl-tree--node-data br)) |
| 211 | (if (avl-tree--do-delete cmpfun br 0 data) | 217 | (let ((ret (avl-tree--do-delete cmpfun br 0 data test nilflag))) |
| 212 | (avl-tree--del-balance root branch 0))) | 218 | (cons (if (car ret) (avl-tree--del-balance root branch 0)) |
| 219 | (cdr ret)))) | ||
| 213 | 220 | ||
| 214 | ((funcall cmpfun (avl-tree--node-data br) data) | 221 | ((funcall cmpfun (avl-tree--node-data br) data) |
| 215 | (if (avl-tree--do-delete cmpfun br 1 data) | 222 | (let ((ret (avl-tree--do-delete cmpfun br 1 data test nilflag))) |
| 216 | (avl-tree--del-balance root branch 1))) | 223 | (cons (if (car ret) (avl-tree--del-balance root branch 1)) |
| 224 | (cdr ret)))) | ||
| 225 | |||
| 226 | (t ; Found it. | ||
| 227 | ;; if it fails TEST, do nothing | ||
| 228 | (if (and test (not (funcall test (avl-tree--node-data br)))) | ||
| 229 | (cons nil nilflag) | ||
| 230 | (cond | ||
| 231 | ((null (avl-tree--node-right br)) | ||
| 232 | (setf (avl-tree--node-branch root branch) | ||
| 233 | (avl-tree--node-left br)) | ||
| 234 | (cons t (avl-tree--node-data br))) | ||
| 217 | 235 | ||
| 218 | (t | 236 | ((null (avl-tree--node-left br)) |
| 219 | ;; Found it. Let's delete it. | 237 | (setf (avl-tree--node-branch root branch) |
| 220 | (cond | 238 | (avl-tree--node-right br)) |
| 221 | ((null (avl-tree--node-right br)) | 239 | (cons t (avl-tree--node-data br))) |
| 222 | (setf (avl-tree--node-branch root branch) (avl-tree--node-left br)) | 240 | |
| 223 | t) | 241 | (t |
| 242 | (if (avl-tree--do-del-internal br 0 br) | ||
| 243 | (cons (avl-tree--del-balance root branch 0) | ||
| 244 | (avl-tree--node-data br)) | ||
| 245 | (cons nil (avl-tree--node-data br)))) | ||
| 246 | )))))) | ||
| 224 | 247 | ||
| 225 | ((null (avl-tree--node-left br)) | ||
| 226 | (setf (avl-tree--node-branch root branch) | ||
| 227 | (avl-tree--node-right br)) | ||
| 228 | t) | ||
| 229 | 248 | ||
| 230 | (t | ||
| 231 | (if (avl-tree--do-del-internal br 0 br) | ||
| 232 | (avl-tree--del-balance root branch 0)))))))) | ||
| 233 | 249 | ||
| 234 | ;; ---------------------------------------------------------------- | 250 | ;; ---------------------------------------------------------------- |
| 235 | ;; Entering data | 251 | ;; Entering data |
| @@ -284,27 +300,44 @@ Return t if the height of the tree has grown." | |||
| 284 | (avl-tree--node-branch node branch)) 0)) | 300 | (avl-tree--node-branch node branch)) 0)) |
| 285 | nil)))) | 301 | nil)))) |
| 286 | 302 | ||
| 287 | (defun avl-tree--do-enter (cmpfun root branch data) | 303 | (defun avl-tree--do-enter (cmpfun root branch data &optional updatefun) |
| 288 | ;; Return t if height of tree ROOT has grown. INTERNAL USE ONLY. | 304 | "Enter DATA in BRANCH of ROOT node. |
| 305 | \(See `avl-tree-enter' for UPDATEFUN). | ||
| 306 | |||
| 307 | Return cons cell (GREW . DATA), where GREW is t if height | ||
| 308 | of tree ROOT has grown and nil otherwise, and DATA is the | ||
| 309 | inserted data." | ||
| 289 | (let ((br (avl-tree--node-branch root branch))) | 310 | (let ((br (avl-tree--node-branch root branch))) |
| 290 | (cond | 311 | (cond |
| 291 | ((null br) | 312 | ((null br) |
| 292 | ;; Data not in tree, insert it. | 313 | ;; Data not in tree, insert it. |
| 293 | (setf (avl-tree--node-branch root branch) | 314 | (setf (avl-tree--node-branch root branch) |
| 294 | (avl-tree--node-create nil nil data 0)) | 315 | (avl-tree--node-create nil nil data 0)) |
| 295 | t) | 316 | (cons t data)) |
| 296 | 317 | ||
| 297 | ((funcall cmpfun data (avl-tree--node-data br)) | 318 | ((funcall cmpfun data (avl-tree--node-data br)) |
| 298 | (and (avl-tree--do-enter cmpfun br 0 data) | 319 | (let ((ret (avl-tree--do-enter cmpfun br 0 data updatefun))) |
| 299 | (avl-tree--enter-balance root branch 0))) | 320 | (cons (and (car ret) (avl-tree--enter-balance root branch 0)) |
| 321 | (cdr ret)))) | ||
| 300 | 322 | ||
| 301 | ((funcall cmpfun (avl-tree--node-data br) data) | 323 | ((funcall cmpfun (avl-tree--node-data br) data) |
| 302 | (and (avl-tree--do-enter cmpfun br 1 data) | 324 | (let ((ret (avl-tree--do-enter cmpfun br 1 data updatefun))) |
| 303 | (avl-tree--enter-balance root branch 1))) | 325 | (cons (and (car ret) (avl-tree--enter-balance root branch 1)) |
| 326 | (cdr ret)))) | ||
| 304 | 327 | ||
| 328 | ;; Data already in tree, update it. | ||
| 305 | (t | 329 | (t |
| 306 | (setf (avl-tree--node-data br) data) | 330 | (let ((newdata |
| 307 | nil)))) | 331 | (if updatefun |
| 332 | (funcall updatefun data (avl-tree--node-data br)) | ||
| 333 | data))) | ||
| 334 | (if (or (funcall cmpfun newdata data) | ||
| 335 | (funcall cmpfun data newdata)) | ||
| 336 | (error "avl-tree-enter:\ | ||
| 337 | updated data does not match existing data")) | ||
| 338 | (setf (avl-tree--node-data br) newdata) | ||
| 339 | (cons nil newdata)) ; return value | ||
| 340 | )))) | ||
| 308 | 341 | ||
| 309 | ;; ---------------------------------------------------------------- | 342 | ;; ---------------------------------------------------------------- |
| 310 | 343 | ||
| @@ -348,6 +381,30 @@ itself." | |||
| 348 | (avl-tree--node-data root) | 381 | (avl-tree--node-data root) |
| 349 | (avl-tree--node-balance root)))) | 382 | (avl-tree--node-balance root)))) |
| 350 | 383 | ||
| 384 | (defstruct (avl-tree--stack | ||
| 385 | (:constructor nil) | ||
| 386 | (:constructor avl-tree--stack-create | ||
| 387 | (tree &optional reverse | ||
| 388 | &aux | ||
| 389 | (store | ||
| 390 | (if (avl-tree-empty tree) | ||
| 391 | nil | ||
| 392 | (list (avl-tree--root tree)))))) | ||
| 393 | (:copier nil)) | ||
| 394 | reverse store) | ||
| 395 | |||
| 396 | (defalias 'avl-tree-stack-p 'avl-tree--stack-p | ||
| 397 | "Return t if argument is an avl-tree-stack, nil otherwise.") | ||
| 398 | |||
| 399 | (defun avl-tree--stack-repopulate (stack) | ||
| 400 | ;; Recursively push children of the node at the head of STACK onto the | ||
| 401 | ;; front of the STACK, until a leaf is reached. | ||
| 402 | (let ((node (car (avl-tree--stack-store stack))) | ||
| 403 | (dir (if (avl-tree--stack-reverse stack) 1 0))) | ||
| 404 | (when node ; check for emtpy stack | ||
| 405 | (while (setq node (avl-tree--node-branch node dir)) | ||
| 406 | (push node (avl-tree--stack-store stack)))))) | ||
| 407 | |||
| 351 | 408 | ||
| 352 | ;; ================================================================ | 409 | ;; ================================================================ |
| 353 | ;;; The public functions which operate on AVL trees. | 410 | ;;; The public functions which operate on AVL trees. |
| @@ -367,30 +424,56 @@ and returns non-nil if A is less than B, and nil otherwise.") | |||
| 367 | "Return t if avl tree TREE is emtpy, otherwise return nil." | 424 | "Return t if avl tree TREE is emtpy, otherwise return nil." |
| 368 | (null (avl-tree--root tree))) | 425 | (null (avl-tree--root tree))) |
| 369 | 426 | ||
| 370 | (defun avl-tree-enter (tree data) | 427 | (defun avl-tree-enter (tree data &optional updatefun) |
| 371 | "In the avl tree TREE insert DATA. | 428 | "Insert DATA into the avl tree TREE. |
| 372 | Return DATA." | 429 | |
| 373 | (avl-tree--do-enter (avl-tree--cmpfun tree) | 430 | If an element that matches DATA (according to the tree's |
| 374 | (avl-tree--dummyroot tree) | 431 | comparison function, see `avl-tree-create') already exists in |
| 375 | 0 | 432 | TREE, it will be replaced by DATA by default. |
| 376 | data) | 433 | |
| 377 | data) | 434 | If UPDATEFUN is supplied and an element matching DATA already |
| 378 | 435 | exists in TREE, UPDATEFUN is called with two arguments: DATA, and | |
| 379 | (defun avl-tree-delete (tree data) | 436 | the matching element. Its return value replaces the existing |
| 380 | "From the avl tree TREE, delete DATA. | 437 | element. This value *must* itself match DATA (and hence the |
| 381 | Return the element in TREE which matched DATA, | 438 | pre-existing data), or an error will occur. |
| 382 | nil if no element matched." | 439 | |
| 383 | (avl-tree--do-delete (avl-tree--cmpfun tree) | 440 | Returns the new data." |
| 384 | (avl-tree--dummyroot tree) | 441 | (cdr (avl-tree--do-enter (avl-tree--cmpfun tree) |
| 385 | 0 | 442 | (avl-tree--dummyroot tree) |
| 386 | data)) | 443 | 0 data updatefun))) |
| 387 | 444 | ||
| 388 | (defun avl-tree-member (tree data) | 445 | (defun avl-tree-delete (tree data &optional test nilflag) |
| 446 | "Delete the element matching DATA from the avl tree TREE. | ||
| 447 | Matching uses the comparison function previously specified in | ||
| 448 | `avl-tree-create' when TREE was created. | ||
| 449 | |||
| 450 | Returns the deleted element, or nil if no matching element was | ||
| 451 | found. | ||
| 452 | |||
| 453 | Optional argument NILFLAG specifies a value to return instead of | ||
| 454 | nil if nothing was deleted, so that this case can be | ||
| 455 | distinguished from the case of a successfully deleted null | ||
| 456 | element. | ||
| 457 | |||
| 458 | If supplied, TEST specifies a test that a matching element must | ||
| 459 | pass before it is deleted. If a matching element is found, it is | ||
| 460 | passed as an argument to TEST, and is deleted only if the return | ||
| 461 | value is non-nil." | ||
| 462 | (cdr (avl-tree--do-delete (avl-tree--cmpfun tree) | ||
| 463 | (avl-tree--dummyroot tree) | ||
| 464 | 0 data test nilflag))) | ||
| 465 | |||
| 466 | |||
| 467 | (defun avl-tree-member (tree data &optional nilflag) | ||
| 389 | "Return the element in the avl tree TREE which matches DATA. | 468 | "Return the element in the avl tree TREE which matches DATA. |
| 390 | Matching uses the compare function previously specified in | 469 | Matching uses the comparison function previously specified in |
| 391 | `avl-tree-create' when TREE was created. | 470 | `avl-tree-create' when TREE was created. |
| 392 | 471 | ||
| 393 | If there is no such element in the tree, the value is nil." | 472 | If there is no such element in the tree, nil is |
| 473 | returned. Optional argument NILFLAG specifies a value to return | ||
| 474 | instead of nil in this case. This allows non-existent elements to | ||
| 475 | be distinguished from a null element. (See also | ||
| 476 | `avl-tree-member-p', which does this for you.)" | ||
| 394 | (let ((node (avl-tree--root tree)) | 477 | (let ((node (avl-tree--root tree)) |
| 395 | (compare-function (avl-tree--cmpfun tree))) | 478 | (compare-function (avl-tree--cmpfun tree))) |
| 396 | (catch 'found | 479 | (catch 'found |
| @@ -401,7 +484,16 @@ If there is no such element in the tree, the value is nil." | |||
| 401 | ((funcall compare-function (avl-tree--node-data node) data) | 484 | ((funcall compare-function (avl-tree--node-data node) data) |
| 402 | (setq node (avl-tree--node-right node))) | 485 | (setq node (avl-tree--node-right node))) |
| 403 | (t (throw 'found (avl-tree--node-data node))))) | 486 | (t (throw 'found (avl-tree--node-data node))))) |
| 404 | nil))) | 487 | nilflag))) |
| 488 | |||
| 489 | |||
| 490 | (defun avl-tree-member-p (tree data) | ||
| 491 | "Return t if an element matching DATA exists in the avl tree TREE, | ||
| 492 | otherwise return nil. Matching uses the comparison function | ||
| 493 | previously specified in `avl-tree-create' when TREE was created." | ||
| 494 | (let ((flag '(nil))) | ||
| 495 | (not (eq (avl-tree-member tree data flag) flag)))) | ||
| 496 | |||
| 405 | 497 | ||
| 406 | (defun avl-tree-map (__map-function__ tree &optional reverse) | 498 | (defun avl-tree-map (__map-function__ tree &optional reverse) |
| 407 | "Modify all elements in the avl tree TREE by applying FUNCTION. | 499 | "Modify all elements in the avl tree TREE by applying FUNCTION. |
| @@ -418,6 +510,57 @@ descending order if REVERSE is non-nil." | |||
| 418 | (avl-tree--root tree) | 510 | (avl-tree--root tree) |
| 419 | (if reverse 1 0))) | 511 | (if reverse 1 0))) |
| 420 | 512 | ||
| 513 | |||
| 514 | (defun avl-tree-mapc (__map-function__ tree &optional reverse) | ||
| 515 | "Apply FUNCTION to all elements in avl tree TREE, | ||
| 516 | for side-effect only. | ||
| 517 | |||
| 518 | FUNCTION is applied to the elements in ascending order, or | ||
| 519 | descending order if REVERSE is non-nil." | ||
| 520 | (avl-tree--mapc | ||
| 521 | (lambda (node) | ||
| 522 | (funcall __map-function__ (avl-tree--node-data node))) | ||
| 523 | (avl-tree--root tree) | ||
| 524 | (if reverse 1 0))) | ||
| 525 | |||
| 526 | |||
| 527 | (defun avl-tree-mapf | ||
| 528 | (__map-function__ combinator tree &optional reverse) | ||
| 529 | "Apply FUNCTION to all elements in avl tree TREE, | ||
| 530 | and combine the results using COMBINATOR. | ||
| 531 | |||
| 532 | The FUNCTION is applied and the results are combined in ascending | ||
| 533 | order, or descending order if REVERSE is non-nil." | ||
| 534 | (let (avl-tree-mapf--accumulate) | ||
| 535 | (avl-tree--mapc | ||
| 536 | (lambda (node) | ||
| 537 | (setq avl-tree-mapf--accumulate | ||
| 538 | (funcall combinator | ||
| 539 | (funcall __map-function__ | ||
| 540 | (avl-tree--node-data node)) | ||
| 541 | avl-tree-mapf--accumulate))) | ||
| 542 | (avl-tree--root tree) | ||
| 543 | (if reverse 0 1)) | ||
| 544 | (nreverse avl-tree-mapf--accumulate))) | ||
| 545 | |||
| 546 | |||
| 547 | (defun avl-tree-mapcar (__map-function__ tree &optional reverse) | ||
| 548 | "Apply FUNCTION to all elements in avl tree TREE, | ||
| 549 | and make a list of the results. | ||
| 550 | |||
| 551 | The FUNCTION is applied and the list constructed in ascending | ||
| 552 | order, or descending order if REVERSE is non-nil. | ||
| 553 | |||
| 554 | Note that if you don't care about the order in which FUNCTION is | ||
| 555 | applied, just that the resulting list is in the correct order, | ||
| 556 | then | ||
| 557 | |||
| 558 | (avl-tree-mapf function 'cons tree (not reverse)) | ||
| 559 | |||
| 560 | is more efficient." | ||
| 561 | (nreverse (avl-tree-mapf __map-function__ 'cons tree reverse))) | ||
| 562 | |||
| 563 | |||
| 421 | (defun avl-tree-first (tree) | 564 | (defun avl-tree-first (tree) |
| 422 | "Return the first element in TREE, or nil if TREE is empty." | 565 | "Return the first element in TREE, or nil if TREE is empty." |
| 423 | (let ((node (avl-tree--root tree))) | 566 | (let ((node (avl-tree--root tree))) |
| @@ -460,6 +603,65 @@ descending order if REVERSE is non-nil." | |||
| 460 | "Clear the avl tree TREE." | 603 | "Clear the avl tree TREE." |
| 461 | (setf (avl-tree--root tree) nil)) | 604 | (setf (avl-tree--root tree) nil)) |
| 462 | 605 | ||
| 606 | |||
| 607 | (defun avl-tree-stack (tree &optional reverse) | ||
| 608 | "Return an object that behaves like a sorted stack | ||
| 609 | of all elements of TREE. | ||
| 610 | |||
| 611 | If REVERSE is non-nil, the stack is sorted in reverse order. | ||
| 612 | \(See also `avl-tree-stack-pop'\). | ||
| 613 | |||
| 614 | Note that any modification to TREE *immediately* invalidates all | ||
| 615 | avl-tree-stacks created before the modification (in particular, | ||
| 616 | calling `avl-tree-stack-pop' will give unpredictable results). | ||
| 617 | |||
| 618 | Operations on these objects are significantly more efficient than | ||
| 619 | constructing a real stack with `avl-tree-flatten' and using | ||
| 620 | standard stack functions. As such, they can be useful in | ||
| 621 | implementing efficient algorithms of AVL trees. However, in cases | ||
| 622 | where mapping functions `avl-tree-mapc', `avl-tree-mapcar' or | ||
| 623 | `avl-tree-mapf' would be sufficient, it is better to use one of | ||
| 624 | those instead." | ||
| 625 | (let ((stack (avl-tree--stack-create tree reverse))) | ||
| 626 | (avl-tree--stack-repopulate stack) | ||
| 627 | stack)) | ||
| 628 | |||
| 629 | |||
| 630 | (defun avl-tree-stack-pop (avl-tree-stack &optional nilflag) | ||
| 631 | "Pop the first element from AVL-TREE-STACK. | ||
| 632 | \(See also `avl-tree-stack'\). | ||
| 633 | |||
| 634 | Returns nil if the stack is empty, or NILFLAG if specified. (The | ||
| 635 | latter allows an empty stack to be distinguished from a null | ||
| 636 | element stored in the AVL tree.)" | ||
| 637 | (let (node next) | ||
| 638 | (if (not (setq node (pop (avl-tree--stack-store avl-tree-stack)))) | ||
| 639 | nilflag | ||
| 640 | (when (setq next | ||
| 641 | (avl-tree--node-branch | ||
| 642 | node | ||
| 643 | (if (avl-tree--stack-reverse avl-tree-stack) 0 1))) | ||
| 644 | (push next (avl-tree--stack-store avl-tree-stack)) | ||
| 645 | (avl-tree--stack-repopulate avl-tree-stack)) | ||
| 646 | (avl-tree--node-data node)))) | ||
| 647 | |||
| 648 | |||
| 649 | (defun avl-tree-stack-first (avl-tree-stack &optional nilflag) | ||
| 650 | "Return the first element of AVL-TREE-STACK, without removing it | ||
| 651 | from the stack. | ||
| 652 | |||
| 653 | Returns nil if the stack is empty, or NILFLAG if specified. (The | ||
| 654 | latter allows an empty stack to be distinguished from a null | ||
| 655 | element stored in the AVL tree.)" | ||
| 656 | (or (car (avl-tree--stack-store avl-tree-stack)) | ||
| 657 | nilflag)) | ||
| 658 | |||
| 659 | |||
| 660 | (defun avl-tree-stack-empty-p (avl-tree-stack) | ||
| 661 | "Return t if AVL-TREE-STACK is empty, nil otherwise." | ||
| 662 | (null (avl-tree--stack-store avl-tree-stack))) | ||
| 663 | |||
| 664 | |||
| 463 | (provide 'avl-tree) | 665 | (provide 'avl-tree) |
| 464 | 666 | ||
| 465 | ;;; avl-tree.el ends here | 667 | ;;; avl-tree.el ends here |