comparison lisp/emacs-lisp/avl-tree.el @ 83676:27d11c1d4e46

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 857-862) - Update from CVS - Merge from emacs--rel--22 - Update from CVS: lisp/emacs-lisp/avl-tree.el: New file. * emacs--rel--22 (patch 97-100) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 246-247) - Update from CVS Revision: emacs@sv.gnu.org/emacs--multi-tty--0--patch-38
author Miles Bader <miles@gnu.org>
date Mon, 27 Aug 2007 09:21:49 +0000
parents 7224e10a56f5
children 17a8beea7b8c
comparison
equal deleted inserted replaced
83675:67601f702028 83676:27d11c1d4e46
1 ;;; avl-tree.el --- balanced binary trees, AVL-trees
2
3 ;; Copyright (C) 1995, 2007 Free Software Foundation, Inc.
4
5 ;; Author: Per Cederqvist <ceder@lysator.liu.se>
6 ;; Inge Wallin <inge@lysator.liu.se>
7 ;; Thomas Bellman <bellman@lysator.liu.se>
8 ;; Maintainer: FSF
9 ;; Created: 10 May 1991
10 ;; Keywords: extensions, data structures
11
12 ;; This file is part of GNU Emacs.
13
14 ;; GNU Emacs is free software; you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation; either version 3, or (at your option)
17 ;; any later version.
18
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
23
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 ;; Boston, MA 02110-1301, USA.
28
29 ;;; Commentary:
30
31 ;; An AVL tree is a nearly-perfect balanced binary tree. A tree
32 ;; consists of two cons cells, the first one holding the tag
33 ;; 'AVL-TREE in the car cell, and the second one having the tree
34 ;; in the car and the compare function in the cdr cell. The tree has
35 ;; a dummy node as its root with the real tree in the left pointer.
36 ;;
37 ;; Each node of the tree consists of one data element, one left
38 ;; sub-tree and one right sub-tree. Each node also has a balance
39 ;; count, which is the difference in depth of the left and right
40 ;; sub-trees.
41 ;;
42 ;; The "public" functions (prefixed with "avl-tree") are:
43 ;; -create, -p, -compare-function, -empty, -enter, -delete,
44 ;; -member, -map, -first, -last, -copy, -flatten, -size, -clear.
45
46 ;;; Code:
47
48 ;;; ================================================================
49 ;;; Functions and macros handling an AVL tree node.
50
51 (defmacro avl-tree-node-create (left right data balance)
52 ;; Create and return an avl-tree node.
53 `(vector ,left ,right ,data ,balance))
54
55 (defmacro avl-tree-node-left (node)
56 ;; Return the left pointer of NODE.
57 `(aref ,node 0))
58
59 (defmacro avl-tree-node-right (node)
60 ;; Return the right pointer of NODE.
61 `(aref ,node 1))
62
63 (defmacro avl-tree-node-data (node)
64 ;; Return the data of NODE.
65 `(aref ,node 2))
66
67 (defmacro avl-tree-node-set-left (node newleft)
68 ;; Set the left pointer of NODE to NEWLEFT.
69 `(aset ,node 0 ,newleft))
70
71 (defmacro avl-tree-node-set-right (node newright)
72 ;; Set the right pointer of NODE to NEWRIGHT.
73 `(aset ,node 1 ,newright))
74
75 (defmacro avl-tree-node-set-data (node newdata)
76 ;; Set the data of NODE to NEWDATA.
77 `(aset ,node 2 ,newdata))
78
79 (defmacro avl-tree-node-branch (node branch)
80 "Get value of a branch of a node.
81
82 NODE is the node, and BRANCH is the branch.
83 0 for left pointer, 1 for right pointer and 2 for the data.\""
84 `(aref ,node ,branch))
85
86 (defmacro avl-tree-node-set-branch (node branch newval)
87 "Set value of a branch of a node.
88
89 NODE is the node, and BRANCH is the branch.
90 0 for left pointer, 1 for the right pointer and 2 for the data.
91 NEWVAL is new value of the branch.\""
92 `(aset ,node ,branch ,newval))
93
94 (defmacro avl-tree-node-balance (node)
95 ;; Return the balance field of a node.
96 `(aref ,node 3))
97
98 (defmacro avl-tree-node-set-balance (node newbal)
99 ;; Set the balance field of a node.
100 `(aset ,node 3 ,newbal))
101
102
103 ;;; ================================================================
104 ;;; Internal functions for use in the AVL tree package
105
106 (defmacro avl-tree-root (tree)
107 ;; Return the root node for an avl-tree. INTERNAL USE ONLY.
108 `(avl-tree-node-left (car (cdr ,tree))))
109
110 (defmacro avl-tree-dummyroot (tree)
111 ;; Return the dummy node of an avl-tree. INTERNAL USE ONLY.
112 `(car (cdr ,tree)))
113
114 (defmacro avl-tree-cmpfun (tree)
115 ;; Return the compare function of AVL tree TREE. INTERNAL USE ONLY.
116 `(cdr (cdr ,tree)))
117
118 ;; ----------------------------------------------------------------
119 ;; Deleting data
120
121 (defun avl-tree-del-balance1 (node branch)
122 ;; Rebalance a tree and return t if the height of the tree has shrunk.
123 (let ((br (avl-tree-node-branch node branch))
124 p1 b1 p2 b2 result)
125 (cond
126 ((< (avl-tree-node-balance br) 0)
127 (avl-tree-node-set-balance br 0)
128 t)
129
130 ((= (avl-tree-node-balance br) 0)
131 (avl-tree-node-set-balance br +1)
132 nil)
133
134 (t
135 ;; Rebalance.
136 (setq p1 (avl-tree-node-right br)
137 b1 (avl-tree-node-balance p1))
138 (if (>= b1 0)
139 ;; Single RR rotation.
140 (progn
141 (avl-tree-node-set-right br (avl-tree-node-left p1))
142 (avl-tree-node-set-left p1 br)
143 (if (= 0 b1)
144 (progn
145 (avl-tree-node-set-balance br +1)
146 (avl-tree-node-set-balance p1 -1)
147 (setq result nil))
148 (avl-tree-node-set-balance br 0)
149 (avl-tree-node-set-balance p1 0)
150 (setq result t))
151 (avl-tree-node-set-branch node branch p1)
152 result)
153
154 ;; Double RL rotation.
155 (setq p2 (avl-tree-node-left p1)
156 b2 (avl-tree-node-balance p2))
157 (avl-tree-node-set-left p1 (avl-tree-node-right p2))
158 (avl-tree-node-set-right p2 p1)
159 (avl-tree-node-set-right br (avl-tree-node-left p2))
160 (avl-tree-node-set-left p2 br)
161 (if (> b2 0)
162 (avl-tree-node-set-balance br -1)
163 (avl-tree-node-set-balance br 0))
164 (if (< b2 0)
165 (avl-tree-node-set-balance p1 +1)
166 (avl-tree-node-set-balance p1 0))
167 (avl-tree-node-set-branch node branch p2)
168 (avl-tree-node-set-balance p2 0)
169 t)))))
170
171 (defun avl-tree-del-balance2 (node branch)
172 (let ((br (avl-tree-node-branch node branch))
173 p1 b1 p2 b2 result)
174 (cond
175 ((> (avl-tree-node-balance br) 0)
176 (avl-tree-node-set-balance br 0)
177 t)
178
179 ((= (avl-tree-node-balance br) 0)
180 (avl-tree-node-set-balance br -1)
181 nil)
182
183 (t
184 ;; Rebalance.
185 (setq p1 (avl-tree-node-left br)
186 b1 (avl-tree-node-balance p1))
187 (if (<= b1 0)
188 ;; Single LL rotation.
189 (progn
190 (avl-tree-node-set-left br (avl-tree-node-right p1))
191 (avl-tree-node-set-right p1 br)
192 (if (= 0 b1)
193 (progn
194 (avl-tree-node-set-balance br -1)
195 (avl-tree-node-set-balance p1 +1)
196 (setq result nil))
197 (avl-tree-node-set-balance br 0)
198 (avl-tree-node-set-balance p1 0)
199 (setq result t))
200 (avl-tree-node-set-branch node branch p1)
201 result)
202
203 ;; Double LR rotation.
204 (setq p2 (avl-tree-node-right p1)
205 b2 (avl-tree-node-balance p2))
206 (avl-tree-node-set-right p1 (avl-tree-node-left p2))
207 (avl-tree-node-set-left p2 p1)
208 (avl-tree-node-set-left br (avl-tree-node-right p2))
209 (avl-tree-node-set-right p2 br)
210 (if (< b2 0)
211 (avl-tree-node-set-balance br +1)
212 (avl-tree-node-set-balance br 0))
213 (if (> b2 0)
214 (avl-tree-node-set-balance p1 -1)
215 (avl-tree-node-set-balance p1 0))
216 (avl-tree-node-set-branch node branch p2)
217 (avl-tree-node-set-balance p2 0)
218 t)))))
219
220 (defun avl-tree-do-del-internal (node branch q)
221 (let ((br (avl-tree-node-branch node branch)))
222 (if (avl-tree-node-right br)
223 (if (avl-tree-do-del-internal br +1 q)
224 (avl-tree-del-balance2 node branch))
225 (avl-tree-node-set-data q (avl-tree-node-data br))
226 (avl-tree-node-set-branch node branch
227 (avl-tree-node-left br))
228 t)))
229
230 (defun avl-tree-do-delete (cmpfun root branch data)
231 ;; Return t if the height of the tree has shrunk.
232 (let ((br (avl-tree-node-branch root branch)))
233 (cond
234 ((null br)
235 nil)
236
237 ((funcall cmpfun data (avl-tree-node-data br))
238 (if (avl-tree-do-delete cmpfun br 0 data)
239 (avl-tree-del-balance1 root branch)))
240
241 ((funcall cmpfun (avl-tree-node-data br) data)
242 (if (avl-tree-do-delete cmpfun br 1 data)
243 (avl-tree-del-balance2 root branch)))
244
245 (t
246 ;; Found it. Let's delete it.
247 (cond
248 ((null (avl-tree-node-right br))
249 (avl-tree-node-set-branch root branch (avl-tree-node-left br))
250 t)
251
252 ((null (avl-tree-node-left br))
253 (avl-tree-node-set-branch root branch (avl-tree-node-right br))
254 t)
255
256 (t
257 (if (avl-tree-do-del-internal br 0 br)
258 (avl-tree-del-balance1 root branch))))))))
259
260 ;; ----------------------------------------------------------------
261 ;; Entering data
262
263 (defun avl-tree-enter-balance1 (node branch)
264 ;; Rebalance a tree and return t if the height of the tree has grown.
265 (let ((br (avl-tree-node-branch node branch))
266 p1 p2 b2 result)
267 (cond
268 ((< (avl-tree-node-balance br) 0)
269 (avl-tree-node-set-balance br 0)
270 nil)
271
272 ((= (avl-tree-node-balance br) 0)
273 (avl-tree-node-set-balance br +1)
274 t)
275
276 (t
277 ;; Tree has grown => Rebalance.
278 (setq p1 (avl-tree-node-right br))
279 (if (> (avl-tree-node-balance p1) 0)
280 ;; Single RR rotation.
281 (progn
282 (avl-tree-node-set-right br (avl-tree-node-left p1))
283 (avl-tree-node-set-left p1 br)
284 (avl-tree-node-set-balance br 0)
285 (avl-tree-node-set-branch node branch p1))
286
287 ;; Double RL rotation.
288 (setq p2 (avl-tree-node-left p1)
289 b2 (avl-tree-node-balance p2))
290 (avl-tree-node-set-left p1 (avl-tree-node-right p2))
291 (avl-tree-node-set-right p2 p1)
292 (avl-tree-node-set-right br (avl-tree-node-left p2))
293 (avl-tree-node-set-left p2 br)
294 (if (> b2 0)
295 (avl-tree-node-set-balance br -1)
296 (avl-tree-node-set-balance br 0))
297 (if (< b2 0)
298 (avl-tree-node-set-balance p1 +1)
299 (avl-tree-node-set-balance p1 0))
300 (avl-tree-node-set-branch node branch p2))
301 (avl-tree-node-set-balance (avl-tree-node-branch node branch) 0)
302 nil))))
303
304 (defun avl-tree-enter-balance2 (node branch)
305 ;; Return t if the tree has grown.
306 (let ((br (avl-tree-node-branch node branch))
307 p1 p2 b2)
308 (cond
309 ((> (avl-tree-node-balance br) 0)
310 (avl-tree-node-set-balance br 0)
311 nil)
312
313 ((= (avl-tree-node-balance br) 0)
314 (avl-tree-node-set-balance br -1)
315 t)
316
317 (t
318 ;; Balance was -1 => Rebalance.
319 (setq p1 (avl-tree-node-left br))
320 (if (< (avl-tree-node-balance p1) 0)
321 ;; Single LL rotation.
322 (progn
323 (avl-tree-node-set-left br (avl-tree-node-right p1))
324 (avl-tree-node-set-right p1 br)
325 (avl-tree-node-set-balance br 0)
326 (avl-tree-node-set-branch node branch p1))
327
328 ;; Double LR rotation.
329 (setq p2 (avl-tree-node-right p1)
330 b2 (avl-tree-node-balance p2))
331 (avl-tree-node-set-right p1 (avl-tree-node-left p2))
332 (avl-tree-node-set-left p2 p1)
333 (avl-tree-node-set-left br (avl-tree-node-right p2))
334 (avl-tree-node-set-right p2 br)
335 (if (< b2 0)
336 (avl-tree-node-set-balance br +1)
337 (avl-tree-node-set-balance br 0))
338 (if (> b2 0)
339 (avl-tree-node-set-balance p1 -1)
340 (avl-tree-node-set-balance p1 0))
341 (avl-tree-node-set-branch node branch p2))
342 (avl-tree-node-set-balance (avl-tree-node-branch node branch) 0)
343 nil))))
344
345 (defun avl-tree-do-enter (cmpfun root branch data)
346 ;; Return t if height of tree ROOT has grown. INTERNAL USE ONLY.
347 (let ((br (avl-tree-node-branch root branch)))
348 (cond
349 ((null br)
350 ;; Data not in tree, insert it.
351 (avl-tree-node-set-branch
352 root branch (avl-tree-node-create nil nil data 0))
353 t)
354
355 ((funcall cmpfun data (avl-tree-node-data br))
356 (and (avl-tree-do-enter cmpfun br 0 data)
357 (avl-tree-enter-balance2 root branch)))
358
359 ((funcall cmpfun (avl-tree-node-data br) data)
360 (and (avl-tree-do-enter cmpfun br 1 data)
361 (avl-tree-enter-balance1 root branch)))
362
363 (t
364 (avl-tree-node-set-data br data)
365 nil))))
366
367 ;; ----------------------------------------------------------------
368
369 (defun avl-tree-mapc (map-function root)
370 ;; Apply MAP-FUNCTION to all nodes in the tree starting with ROOT.
371 ;; The function is applied in-order.
372 ;;
373 ;; Note: MAP-FUNCTION is applied to the node and not to the data itself.
374 ;; INTERNAL USE ONLY.
375 (let ((node root)
376 (stack nil)
377 (go-left t))
378 (push nil stack)
379 (while node
380 (if (and go-left
381 (avl-tree-node-left node))
382 ;; Do the left subtree first.
383 (progn
384 (push node stack)
385 (setq node (avl-tree-node-left node)))
386 ;; Apply the function...
387 (funcall map-function node)
388 ;; and do the right subtree.
389 (if (avl-tree-node-right node)
390 (setq node (avl-tree-node-right node)
391 go-left t)
392 (setq node (pop stack)
393 go-left nil))))))
394
395 (defun avl-tree-do-copy (root)
396 ;; Copy the avl tree with ROOT as root.
397 ;; Highly recursive. INTERNAL USE ONLY.
398 (if (null root)
399 nil
400 (avl-tree-node-create
401 (avl-tree-do-copy (avl-tree-node-left root))
402 (avl-tree-do-copy (avl-tree-node-right root))
403 (avl-tree-node-data root)
404 (avl-tree-node-balance root))))
405
406
407 ;;; ================================================================
408 ;;; The public functions which operate on AVL trees.
409
410 (defun avl-tree-create (compare-function)
411 "Create a new empty avl tree and return it.
412 COMPARE-FUNCTION is a function which takes two arguments, A and B,
413 and returns non-nil if A is less than B, and nil otherwise."
414 (cons 'AVL-TREE
415 (cons (avl-tree-node-create nil nil nil 0)
416 compare-function)))
417
418 (defun avl-tree-p (obj)
419 "Return t if OBJ is an avl tree, nil otherwise."
420 (eq (car-safe obj) 'AVL-TREE))
421
422 (defun avl-tree-compare-function (tree)
423 "Return the comparison function for the avl tree TREE."
424 (avl-tree-cmpfun tree))
425
426 (defun avl-tree-empty (tree)
427 "Return t if avl tree TREE is emtpy, otherwise return nil."
428 (null (avl-tree-root tree)))
429
430 (defun avl-tree-enter (tree data)
431 "In the avl tree TREE insert DATA.
432 Return DATA."
433 (avl-tree-do-enter (avl-tree-cmpfun tree)
434 (avl-tree-dummyroot tree)
435 0
436 data)
437 data)
438
439 (defun avl-tree-delete (tree data)
440 "From the avl tree TREE, delete DATA.
441 Return the element in TREE which matched DATA,
442 nil if no element matched."
443 (avl-tree-do-delete (avl-tree-cmpfun tree)
444 (avl-tree-dummyroot tree)
445 0
446 data))
447
448 (defun avl-tree-member (tree data)
449 "Return the element in the avl tree TREE which matches DATA.
450 Matching uses the compare function previously specified in
451 `avl-tree-create' when TREE was created.
452
453 If there is no such element in the tree, the value is nil."
454 (let ((node (avl-tree-root tree))
455 (compare-function (avl-tree-cmpfun tree))
456 found)
457 (while (and node
458 (not found))
459 (cond
460 ((funcall compare-function data (avl-tree-node-data node))
461 (setq node (avl-tree-node-left node)))
462 ((funcall compare-function (avl-tree-node-data node) data)
463 (setq node (avl-tree-node-right node)))
464 (t
465 (setq found t))))
466 (if node
467 (avl-tree-node-data node)
468 nil)))
469
470 (defun avl-tree-map (__map-function__ tree)
471 "Apply __MAP-FUNCTION__ to all elements in the avl tree TREE."
472 (avl-tree-mapc
473 (function (lambda (node)
474 (avl-tree-node-set-data
475 node (funcall __map-function__
476 (avl-tree-node-data node)))))
477 (avl-tree-root tree)))
478
479 (defun avl-tree-first (tree)
480 "Return the first element in TREE, or nil if TREE is empty."
481 (let ((node (avl-tree-root tree)))
482 (if node
483 (progn
484 (while (avl-tree-node-left node)
485 (setq node (avl-tree-node-left node)))
486 (avl-tree-node-data node))
487 nil)))
488
489 (defun avl-tree-last (tree)
490 "Return the last element in TREE, or nil if TREE is empty."
491 (let ((node (avl-tree-root tree)))
492 (if node
493 (progn
494 (while (avl-tree-node-right node)
495 (setq node (avl-tree-node-right node)))
496 (avl-tree-node-data node))
497 nil)))
498
499 (defun avl-tree-copy (tree)
500 "Return a copy of the avl tree TREE."
501 (let ((new-tree (avl-tree-create (avl-tree-cmpfun tree))))
502 (avl-tree-node-set-left (avl-tree-dummyroot new-tree)
503 (avl-tree-do-copy (avl-tree-root tree)))
504 new-tree))
505
506 (defun avl-tree-flatten (tree)
507 "Return a sorted list containing all elements of TREE."
508 (nreverse
509 (let ((treelist nil))
510 (avl-tree-mapc
511 (function (lambda (node)
512 (setq treelist (cons (avl-tree-node-data node)
513 treelist))))
514 (avl-tree-root tree))
515 treelist)))
516
517 (defun avl-tree-size (tree)
518 "Return the number of elements in TREE."
519 (let ((treesize 0))
520 (avl-tree-mapc
521 (function (lambda (data)
522 (setq treesize (1+ treesize))
523 data))
524 (avl-tree-root tree))
525 treesize))
526
527 (defun avl-tree-clear (tree)
528 "Clear the avl tree TREE."
529 (avl-tree-node-set-left (avl-tree-dummyroot tree) nil))
530
531 (provide 'avl-tree)
532
533 ;; arch-tag: 47e26701-43c9-4222-bd79-739eac6357a9
534 ;;; avl-tree.el ends here